<html>
<head>
<title>Synchronet JavaScript Object Model Reference</title>
<STYLE>
	OL LI                { cursor: hand; }
	UL LI                { display: none;list-style: square; }
	.showList LI         { display: list-item; }
	caption              { display: table-caption; text-align: left; caption-side: top; }
</STYLE>
</head>
<body>
<font face=arial,helvetica>
<h1>Synchronet JavaScript Object Model Reference</h1>
Generated for <b>Synchronet v3.18c</b>, compiled Sep 24 2020 22:42
<br><font size=-1>
Property and Method version numbers (when available) indicate the Synchronet version when the item was added or modified.
</font>
<ol type=square>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#global"><b>global</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#global_methods>methods</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#global_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#js"><b>js</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#js_methods>methods</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#js_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#system"><b>system</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#system_methods>methods</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#system_properties>properties</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#system.stats"><b>system.stats</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#system.stats_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#system.node_list"><b>system.node_list</b></a> array
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#system.node_list_properties>properties</a>
</ul>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#server"><b>server</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#server_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#client"><b>client</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#client_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#user"><b>user</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#user_methods>methods</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#user_properties>properties</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#user.stats"><b>user.stats</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#user.stats_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#user.security"><b>user.security</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#user.security_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#user.limits"><b>user.limits</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#user.limits_properties>properties</a>
</ul>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#bbs"><b>bbs</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#bbs_methods>methods</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#bbs.mods"><b>bbs.mods</b></a> object
<ul>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#bbs_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#console"><b>console</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#console_methods>methods</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#console_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#msg_area"><b>msg_area</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#msg_area_properties>properties</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#msg_area.grp"><b>msg_area.grp</b></a> object
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#msg_area.sub"><b>msg_area.sub</b></a> object
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#msg_area.grp_list"><b>msg_area.grp_list</b></a> array
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#msg_area.grp_list_properties>properties</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#msg_area.grp_list.sub_list"><b>msg_area.grp_list.sub_list</b></a> array
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#msg_area.grp_list.sub_list_properties>properties</a>
</ul>
</ul>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#file_area"><b>file_area</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#file_area_properties>properties</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#file_area.lib"><b>file_area.lib</b></a> object
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#file_area.dir"><b>file_area.dir</b></a> object
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#file_area.lib_list"><b>file_area.lib_list</b></a> array
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#file_area.lib_list_properties>properties</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#file_area.lib_list.dir_list"><b>file_area.lib_list.dir_list</b></a> array
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#file_area.lib_list.dir_list_properties>properties</a>
</ul>
</ul>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#xtrn_area"><b>xtrn_area</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#xtrn_area.sec"><b>xtrn_area.sec</b></a> object
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#xtrn_area.prog"><b>xtrn_area.prog</b></a> object
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#xtrn_area.sec_list"><b>xtrn_area.sec_list</b></a> array
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#xtrn_area.sec_list_properties>properties</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#xtrn_area.sec_list.prog_list"><b>xtrn_area.sec_list.prog_list</b></a> array
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#xtrn_area.sec_list.prog_list_properties>properties</a>
</ul>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#xtrn_area.event"><b>xtrn_area.event</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#xtrn_area.event_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#xtrn_area.editor"><b>xtrn_area.editor</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#xtrn_area.editor_properties>properties</a>
</ul>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#MsgBase"><b>MsgBase</b></a> class
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#MsgBase_methods>methods</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#MsgBase_properties>properties</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href="#MsgBase.cfg"><b>MsgBase.cfg</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#MsgBase.cfg_properties>properties</a>
</ul>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#File"><b>File</b></a> class
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#File_methods>methods</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#File_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#Queue"><b>Queue</b></a> class
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#Queue_methods>methods</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#Queue_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#Socket"><b>Socket</b></a> class
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#Socket_methods>methods</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#Socket_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#ConnectedSocket"><b>ConnectedSocket</b></a> class
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#ListeningSocket"><b>ListeningSocket</b></a> class
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#COM"><b>COM</b></a> class
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#COM_methods>methods</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#COM_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#CryptContext"><b>CryptContext</b></a> class
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#CryptContext_methods>methods</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#CryptContext_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#CryptKeyset"><b>CryptKeyset</b></a> class
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#CryptKeyset_methods>methods</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#conio"><b>conio</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#conio_methods>methods</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#conio_properties>properties</a>
</ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
[+] &nbsp<a href="#uifc"><b>uifc</b></a> object
<ul>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#uifc_methods>methods</a>
<li onclick = 'this.className = (this.className == "showList") ? "defaultStyles" : "showList";'
	onselectstart = 'event.returnValue = false;'>
<a href=#uifc_properties>properties</a>
</ul>
</ol>
<h2><a name=global>global object</a>
<br><font size=-1>Top-level functions and properties (common to all servers and services)</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>global</tt>
<a name=global_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>log</b><td>string<td><tt>log([level,] value [,value])
<td>3.11
<td>add a line of text to the server and/or system log, <i>values</i> are typically string constants or variables, <i>level</i> is the debug level/priority (default: <tt>LOG_INFO</tt>)
<tr valign=top><td><b>read</b><td>string<td><tt>read([count])
<td>3.11
<td>read up to count characters from input stream
<tr valign=top><td><b>readln</b><td>string<td><tt>readln([count])
<td>3.11
<td>read a single line, up to count characters, from input stream
<tr valign=top><td><b>write</b><td>void<td><tt>write(value [,value])
<td>3.11
<td>send one or more values (typically strings) to the server output
<tr valign=top><td><b>write_raw</b><td>void<td><tt>write_raw(value [,value])
<td>3.14
<td>send a stream of bytes (possibly containing NULLs or special control code sequences) to the server output
<tr valign=top><td><b>writeln</b><td>void<td><tt>writeln(value [,value])
<td>3.11
<td>send a line of text to the console or event log with automatic line termination (CRLF), <i>values</i> are typically string constants or variables (AKA print)
<tr valign=top><td><b>printf</b><td>string<td><tt>printf(string format [,value][,value])
<td>3.10
<td>print a formatted string - <small>CAUTION: for experienced C programmers ONLY</small>
<tr valign=top><td><b>alert</b><td>void<td><tt>alert(value)
<td>3.10
<td>print an alert message (ala client-side JS)
<tr valign=top><td><b>prompt</b><td>string<td><tt>prompt([value])
<td>3.10
<td>displays a prompt (<i>value</i>) and returns a string of user input (ala clent-side JS)
<tr valign=top><td><b>confirm</b><td>boolean<td><tt>confirm(value)
<td>3.10
<td>displays a Yes/No prompt and returns <i>true</i> or <i>false</i> based on user's confirmation (ala client-side JS, <i>true</i> = yes)
<tr valign=top><td><b>deny</b><td>boolean<td><tt>deny(value)
<td>3.15b
<td>displays a No/Yes prompt and returns <i>true</i> or <i>false</i> based on user's denial (<i>true</i> = no)
<tr valign=top><td><b>exit</b><td>void<td><tt>exit([exit_code])
<td>3.11
<td>stop script execution, optionally setting the global property <tt>exit_code</tt> to the specified numeric value
<tr valign=top><td><b>load</b><td>undefined<td><tt>load([<i>bool</i> background or <i>object</i> scope,] <i>string</i> filename [,args])
<td>3.12
<td>load and execute a JavaScript module (<i>filename</i>), optionally specifying a target <i>scope</i> object (default: <i>this</i>) and a list of arguments to pass to the module (as <i>argv</i>). Returns the result (last executed statement) of the executed script or a newly created <i>Queue</i> object if <i>background</i> is <i>true</i>).<br><br><b>Background</b> (added in v3.12):<br>If <i>background</i> is <i>true</i>, the loaded script runs in the background (in a child thread) but may communicate with the parent script/thread by reading from and/or writing to the <i>parent_queue</i> (an automatically created <i>Queue</i> object). The result (last executed statement) of the executed script (or the optional <i>exit_code</i> passed to the <i>exit()</i> function) will be automatically written to the <i>parent_queue</i> which may be read later by the parent script (using <i>load_result.read()</i>, for example).
<tr valign=top><td><b>require</b><td>undefined<td><tt>require([<i>object</i> scope,] <i>string</i> filename, propname [,args])
<td>3.17
<td>load and execute a JavaScript module (<i>filename</i>), optionally specifying a target <i>scope</i> object (default: <i>this</i>) and a list of arguments to pass to the module (as <i>argv</i>) IF AND ONLY IF the property named <i>propname</i> is not defined in the target scope (a defined symbol with a value of undefined will not cause the script to be loaded). Returns the result (last executed statement) of the executed script or null if the script is not executed. 
<tr valign=top><td><b>mswait</b><td>number<td><tt>mswait([milliseconds=<tt>1</tt>])
<td>3.13
<td>millisecond wait/sleep routine (AKA sleep), returns number of elapsed clock ticks (in v3.13)
<tr valign=top><td><b>yield</b><td>void<td><tt>yield([forced=<tt>true</tt>])
<td>3.11
<td>release current thread time-slice, a <i>forced</i> yield will yield to all other pending tasks (lowering CPU utilization), a non-<i>forced</i> yield will yield only to pending tasks of equal or higher priority. <i>forced</i> defaults to <i>true</i>
<tr valign=top><td><b>random</b><td>number<td><tt>random(max_number=<tt>100</tt>)
<td>3.10
<td>return random integer between <tt>0</tt> and <i>max_number</i>-1
<tr valign=top><td><b>time</b><td>number<td><tt>time()
<td>3.10
<td>return current time and date in Unix (time_t) format (number of seconds since Jan-01-1970)
<tr valign=top><td><b>beep</b><td>void<td><tt>beep([frequency=<tt>500</tt>] [,duration=<tt>500</tt>])
<td>3.10
<td>produce a tone on the local speaker at specified frequency for specified duration (in milliseconds)
<tr valign=top><td><b>sound</b><td>boolean<td><tt>sound([filename])
<td>3.10
<td>play a waveform (.wav) sound file (currently, on Windows platforms only)
<tr valign=top><td><b>ctrl</b><td>string<td><tt>ctrl(number or string)
<td>3.11
<td>return ASCII control character representing character passed - Example: <tt>ctrl('C') returns ''</tt>
<tr valign=top><td><b>ascii</b><td>undefined<td><tt>ascii([string text] or [number value])
<td>3.10
<td>convert single character to numeric ASCII value or vice-versa (returns number OR string)
<tr valign=top><td><b>ascii_str</b><td>string<td><tt>ascii_str(text)
<td>3.10
<td>convert extended-ASCII (CP437) characters in text string to plain US-ASCII equivalent, returns modified string
<tr valign=top><td><b>strip_ctrl</b><td>string<td><tt>strip_ctrl(text)
<td>3.10
<td>strip control characters from string, returns modified string
<tr valign=top><td><b>strip_exascii</b><td>string<td><tt>strip_exascii(text)
<td>3.10
<td>strip all extended-ASCII characters from string, returns modified string
<tr valign=top><td><b>skipsp</b><td>string<td><tt>skipsp(text)
<td>3.15
<td>skip (trim) white-space characters off <b>beginning</b> of string, returns modified string
<tr valign=top><td><b>truncsp</b><td>string<td><tt>truncsp(text)
<td>3.10
<td>truncate (trim) white-space characters off <b>end</b> of string, returns modified string
<tr valign=top><td><b>truncstr</b><td>string<td><tt>truncstr(text, charset)
<td>3.10
<td>truncate (trim) string at first char in <i>charset</i>, returns modified string
<tr valign=top><td><b>lfexpand</b><td>string<td><tt>lfexpand(text)
<td>3.10
<td>expand line-feeds (LF) to carriage-return/line-feeds (CRLF), returns modified string
<tr valign=top><td><b>wildmatch</b><td>boolean<td><tt>wildmatch([case_sensitive=<tt>false</tt>,] string [,pattern=<tt>'*'</tt>] [,path=<tt>false</tt>])
<td>3.14
<td>returns <tt>true</tt> if the <i>string</i> matches the wildcard <i>pattern</i> (wildcards supported are '*' and '?'), if <i>path</i> is <tt>true</tt>, '*' will not match path delimeter characters (e.g. '/')
<tr valign=top><td><b>backslash</b><td>string<td><tt>backslash(path)
<td>3.12
<td>returns directory path with trailing (platform-specific) path delimeter (i.e. "slash" or "backslash")
<tr valign=top><td><b>fullpath</b><td>string<td><tt>fullpath(path)
<td>3.15
<td>Creates an absolute or full path name for the specified relative path name.
<tr valign=top><td><b>file_getname</b><td>string<td><tt>file_getname(path/filename)
<td>3.11
<td>returns filename portion of passed path string
<tr valign=top><td><b>file_getext</b><td>string<td><tt>file_getext(path/filename)
<td>3.11
<td>returns file extension portion of passed path/filename string (including '.') or <i>undefined</i> if no extension is found
<tr valign=top><td><b>file_getcase</b><td>string<td><tt>file_getcase(path/filename)
<td>3.11
<td>returns correct case of filename (long version of filename on Windows) or <i>undefined</i> if the file doesn't exist
<tr valign=top><td><b>file_cfgname</b><td>string<td><tt>file_cfgname(path, filename)
<td>3.12
<td>returns completed configuration filename from supplied <i>path</i> and <i>filename</i>, optionally including the local hostname (e.g. <tt>path/file.<i>host</i>.<i>domain</i>.ext</tt> or <tt>path/file.<i>host</i>.ext</tt>) if such a variation of the filename exists
<tr valign=top><td><b>file_getdosname</b><td>string<td><tt>file_getdosname(path/filename)
<td>3.15
<td>returns DOS-compatible (Micros~1 shortened) version of specified <i>path/filename</i>(on Windows only)<br>returns unmodified <i>path/filename</i> on other platforms
<tr valign=top><td><b>file_exists</b><td>boolean<td><tt>file_exists(path/filename)
<td>3.10
<td>verify a file's existence
<tr valign=top><td><b>file_remove</b><td>boolean<td><tt>file_remove(path/filename)
<td>3.10
<td>delete a file
<tr valign=top><td><b>file_removecase</b><td>boolean<td><tt>file_removecase(path/filename)
<td>3.14
<td>delete files case insensitively
<tr valign=top><td><b>file_rename</b><td>boolean<td><tt>file_rename(path/oldname, path/newname)
<td>3.11
<td>rename a file, possibly moving it to another directory in the process
<tr valign=top><td><b>file_copy</b><td>boolean<td><tt>file_copy(path/source, path/destination)
<td>3.11
<td>copy a file from one directory or filename to another
<tr valign=top><td><b>file_backup</b><td>boolean<td><tt>file_backup(path/filename [,level=<tt>5</tt>] [,rename=<tt>false</tt>])
<td>3.11
<td>backup the specified <i>filename</i> as <tt>filename.<i>number</i>.extension</tt> where <i>number</i> is the backup number 0 through <i>level</i>-1 (default backup <i>level</i> is 5), if <i>rename</i> is <i>true</i>, the original file is renamed instead of copied (default is <i>false</i>)
<tr valign=top><td><b>file_isdir</b><td>boolean<td><tt>file_isdir(path/filename)
<td>3.10
<td>check if specified <i>filename</i> is a directory
<tr valign=top><td><b>file_attrib</b><td>number<td><tt>file_attrib(path/filename)
<td>3.10
<td>get a file's attributes (same as </i>file_mode()</i> on *nix). On Windows, the return value corresponds with <tt>_finddata_t.attrib</tt> (includes DOS/Windows file system-specific attributes, like <i>hidden</i>, and <i>archive</i>). Returns <tt>-1</tt> if the <i>path/filename</i> does not exist.
<tr valign=top><td><b>file_mode</b><td>number<td><tt>file_mode(path/filename)
<td>3.17c
<td>get a file's type and mode flags (e.g. read/write/execute permissions). The return value corresponds with <tt>struct stat.st_mode</tt>. Returns <tt>-1</tt> if the <i>path/filename</i> does not exist.
<tr valign=top><td><b>file_chmod</b><td>number<td><tt>file_chmod(path/filename, number mode)
<td>3.17c
<td>set a file's permissions flags. The supported <i>mode</i> bit values are system-dependent (e.g. Windows only supports setting or clearing the user-write/0x80 mode flag). Returns <tt>true</tt> if the requested change was successful.
<tr valign=top><td><b>file_date</b><td>number<td><tt>file_date(path/filename)
<td>3.10
<td>get a file's last modified date/time (in time_t format). Returns <tt>-1</tt> if the <i>path/filename</i> does not exist.
<tr valign=top><td><b>file_cdate</b><td>number<td><tt>file_cdate(path/filename)
<td>3.17
<td>get a file's creation date/time (in time_t format). Returns <tt>-1</tt> if the <i>path/filename</i> does not exist.
<tr valign=top><td><b>file_size</b><td>number<td><tt>file_size(path/filename)
<td>3.10
<td>get a file's length (in bytes). Returns <tt>-1</tt> if the <i>path/filename</i> does not exist.
<tr valign=top><td><b>file_utime</b><td>boolean<td><tt>file_utime(path/filename [,access_time=<i>current</i>] [,mod_time=<i>current</i>])
<td>3.11
<td>change a file's last accessed and modification date/time (in time_t format), or change to current time
<tr valign=top><td><b>file_touch</b><td>boolean<td><tt>file_touch(path/filename)
<td>3.11
<td>updates a file's last modification date/time to current time, creating an empty file if it doesn't already exist
<tr valign=top><td><b>file_mutex</b><td>boolean<td><tt>file_mutex(path/filename [,text=<i>local_hostname</i>] [,max_age=<tt>0</tt>])
<td>3.12
<td>attempts to create an mutual-exclusion (e.g. lock) file, optionally with the contents of <i>text</i>. If a non-zero <i>max_age</i> (supported in v3.13b+) is specified and the lock file exists, but is older than this value (in seconds), it is presumed stale and removed/over-written
<tr valign=top><td><b>file_compare</b><td>boolean<td><tt>file_compare(path/file1, path/file2)
<td>3.14
<td>compare 2 files, returning <i>true</i> if they are identical, <i>false</i> otherwise
<tr valign=top><td><b>directory</b><td>array<td><tt>directory(path/pattern [,flags=<tt>GLOB_MARK</tt>])
<td>3.10
<td>returns an array of directory entries, <i>pattern</i> is the path and filename or wildcards to search for (e.g. '/subdir/*.txt'), <i>flags</i> is a bitfield of optional <tt>glob</tt> flags (default is <tt>GLOB_MARK</tt>)
<tr valign=top><td><b>dir_freespace</b><td>number<td><tt>dir_freespace(directory [,unit_size=<tt>1</tt>])
<td>3.11
<td>returns the amount of available disk space in the specified <i>directory</i> using the specified <i>unit_size</i> in bytes (default: 1), specify a <i>unit_size</i> of <tt>1024</tt> to return the available space in <i>kilobytes</i>.
<tr valign=top><td><b>disk_size</b><td>number<td><tt>disk_size(directory [,unit_size=<tt>1</tt>])
<td>3.14
<td>returns the total disk size of the specified <i>directory</i> using the specified <i>unit_size</i> in bytes (default: 1), specify a <i>unit_size</i> of <tt>1024</tt> to return the total disk size in <i>kilobytes</i>.
<tr valign=top><td><b>socket_select</b><td>array<td><tt>socket_select([array of socket objects or descriptors] [,timeout=<tt>0</tt>] [,write=<tt>false</tt>])
<td>3.11
<td>checks an array of socket objects or descriptors for read or write ability (default is <i>read</i>), default timeout value is 0.0 seconds (immediate timeout), returns an array of 0-based index values into the socket array, representing the sockets that were ready for reading or writing, or <i>null</i> on error. If multiple arrays of sockets are passed, they are presumet to be in the order of read, write, and except.  In this case, the write parameter is ignored and an object is returned instead with up to three properties "read", "write", and "except", corresponding to the passed arrays.  Empty passed arrays will not have a corresponding property in the returned object.
<tr valign=top><td><b>mkdir</b><td>boolean<td><tt>mkdir(path/directory)
<td>3.10
<td>make a directory
<tr valign=top><td><b>mkpath</b><td>boolean<td><tt>mkpath(path/directory)
<td>3.15
<td>make a path to a directory (creating all necessary sub-directories). Returns true if the directory already exists.
<tr valign=top><td><b>rmdir</b><td>boolean<td><tt>rmdir(path/directory)
<td>3.10
<td>remove a directory
<tr valign=top><td><b>strftime</b><td>string<td><tt>strftime(format [,time=<i>current</i>])
<td>3.10
<td>return a formatted time string (ala C strftime)
<tr valign=top><td><b>format</b><td>string<td><tt>format(format [,args])
<td>3.10
<td>return a formatted string (ala the standard C <tt>sprintf</tt> function)
<tr valign=top><td><b>html_encode</b><td>string<td><tt>html_encode(text [,ex_ascii=<tt>true</tt>] [,white_space=<tt>true</tt>] [,ansi=<tt>true</tt>] [,ctrl_a=<tt>true</tt>] [, state (object)])
<td>3.11
<td>return an HTML-encoded text string (using standard HTML character entities), escaping IBM extended-ASCII (CP437), white-space characters, ANSI codes, and CTRL-A codes by default.Optionally storing the current ANSI state in <i>state</i> object
<tr valign=top><td><b>html_decode</b><td>string<td><tt>html_decode(html)
<td>3.11
<td>return a decoded HTML-encoded text string
<tr valign=top><td><b>word_wrap</b><td>string<td><tt>word_wrap(text [,line_length=<tt>79</tt> [, orig_line_length=<tt>79</tt> [, handle_quotes=<tt>true</tt> [, is_utf8=<tt>false</tt>]]]])
<td>3.11
<td>returns a word-wrapped version of the text string argument optionally handing quotes magically, <i>line_length</i> defaults to <i>79</i>, <i>orig_line_length</i> defaults to <i>79</i>, <i>handle_quotes</i> defaults to <i>true</i>, and <i>is_utf8</i> defaults to <i>false</i>
<tr valign=top><td><b>quote_msg</b><td>string<td><tt>quote_msg(text [,line_length=<tt>79</tt>] [,prefix=<tt>" > "</tt>])
<td>3.11
<td>returns a quoted version of the message text string argument, <i>line_length</i> defaults to <i>79</i>, <i>prefix</i> defaults to <tt>" > "</tt>
<tr valign=top><td><b>rot13_translate</b><td>string<td><tt>rot13_translate(text)
<td>3.11
<td>returns ROT13-translated version of text string (will encode or decode text)
<tr valign=top><td><b>base64_encode</b><td>string<td><tt>base64_encode(text)
<td>3.11
<td>returns base64-encoded version of text string or <i>null</i> on error
<tr valign=top><td><b>base64_decode</b><td>string<td><tt>base64_decode(text)
<td>3.11
<td>returns base64-decoded text string or <i>null</i> on error
<tr valign=top><td><b>crc16_calc</b><td>number<td><tt>crc16_calc(text)
<td>3.11
<td>calculate and return 16-bit CRC of text string
<tr valign=top><td><b>crc32_calc</b><td>number<td><tt>crc32_calc(text)
<td>3.11
<td>calculate and return 32-bit CRC of text string
<tr valign=top><td><b>chksum_calc</b><td>number<td><tt>chksum_calc(text)
<td>3.11
<td>calculate and return 32-bit checksum of text string
<tr valign=top><td><b>md5_calc</b><td>string<td><tt>md5_calc(text [,hex=<tt>false</tt>])
<td>3.11
<td>calculate and return 128-bit MD5 digest of text string, result encoded in base64 (default) or hexadecimal
<tr valign=top><td><b>resolve_ip</b><td>string<td><tt>resolve_ip(hostname [,array=<tt>false</tt>])
<td>3.11
<td>resolve IP address of specified hostname (AKA gethostbyname).  If <i>array</i> is true (added in 3.17), will return an array of all addresses rather than just the first one (upon success).
<tr valign=top><td><b>resolve_host</b><td>string<td><tt>resolve_host(ip_address)
<td>3.11
<td>resolve hostname of specified IP address (AKA gethostbyaddr)
<tr valign=top><td><b>netaddr_type</b><td>number<td><tt>netaddr_type(email_address)
<td>3.12
<td>returns the proper message <i>net_type</i> for the specified <i>email_address</i>, (e.g. <tt>NET_INTERNET</tt> for Internet e-mail or <tt>NET_NONE</tt> for local e-mail)
<tr valign=top><td><b>list_named_queues</b><td>array<td><tt>list_named_queues()
<td>3.12
<td>returns an array of <i>named queues</i> (created with the <i>Queue</i> constructor)
<tr valign=top><td><b>flags_str</b><td>undefined<td><tt>flags_str([string] or [number])
<td>3.13
<td>convert a string of security flags (letters) into their numeric value or vice-versa (returns number OR string) - (added in v3.13)
<tr valign=top><td><b>utf8_encode</b><td>string<td><tt>utf8_encode([string CP437] or [string UTF16] or [number codepoint])
<td>3.17c
<td>returns UTF-8 encoded version of the specified CP437 text string, UTF-16 encoded text string, or a single Unicode <i>codepoint</i>
<tr valign=top><td><b>utf8_decode</b><td>string<td><tt>utf8_decode(text)
<td>3.17c
<td>returns CP437 representation of UTF-8 encoded text string or <i>null</i> on error (invalid UTF-8)
<tr valign=top><td><b>utf8_get_width</b><td>number<td><tt>utf8_get_width(text)
<td>3.17c
<td>returns the fixed printed-width of the specified string of UTF-8 encoded characters
<tr valign=top><td><b>str_is_utf8</b><td>boolean<td><tt>str_is_utf8(text)
<td>3.17c
<td>returns <tt>true</tt> if the specified string contains only valid UTF-8 encoded and US-ASCII characters
<tr valign=top><td><b>str_is_utf16</b><td>boolean<td><tt>str_is_utf16(text)
<td>3.17c
<td>returns <tt>true</tt> if the specified string contains one or more UTF-16 encoded characters
<tr valign=top><td><b>str_is_ascii</b><td>boolean<td><tt>str_is_ascii(text)
<td>3.17c
<td>returns <tt>true</tt> if the specified string contains only US-ASCII (no CP437 or UTF-8) characters
<tr valign=top><td><b>str_has_ctrl</b><td>boolean<td><tt>str_has_ctrl(text)
<td>3.17c
<td>returns <tt>true</tt> if the specified string contains any control characters (ASCII 0x01 - 0x1F)
</table>
<br>
<table border=1 width=100%>
<caption align=left><b><tt>global</tt>
<a name=global_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr><td><b>argc</b><td>number<td>N/A<td>count of arguments passed to the script</td>
<tr><td><b>argv</b><td>array<td>N/A<td>array of argument strings (argv.length == argc)</td>
<tr><td><b>errno</b><td>number<td>3.10h<td>last system error number</td>
<tr><td><b>errno_str</b><td>string<td>3.10h<td>description of last system error</td>
<tr><td><b>socket_errno</b><td>number<td>3.13a<td>last socket-related error number (same as <i>errno</i> on Unix platforms)</td>
<tr><td><b>socket_errno_str</b><td>string<td>3.18a<td>description of last socket-related error (same as <i>errno_str</i> on Unix platforms)</td>
</table>
<h2><a name=js>js object</a>
<br><font size=-1>JavaScript engine internal control object</font>
<font size=-1> - introduced in v3.11</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>js</tt>
<a name=js_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>eval</b><td>undefined<td><tt>js.eval(script)
<td>3.11
<td>evaluate a JavaScript string in its own (secure) context, returning the result
<tr valign=top><td><b>gc</b><td>void<td><tt>js.gc(forced=<tt>true</tt>)
<td>3.11
<td>perform a garbage collection operation (freeing memory for unused allocated objects), if <i>forced</i> is <i>true</i> (the default) a garbage collection is always performed, otherwise it is only performed if deemed appropriate by the JavaScript engine
<tr valign=top><td><b>on_exit</b><td>void<td><tt>js.on_exit(to_eval)
<td>3.13
<td>add a string to evaluate/execute (LIFO stack) upon script's termination
<tr valign=top><td><b>report_error</b><td>void<td><tt>js.report_error(error [,fatal=<tt>false</tt>])
<td>3.13
<td>report an error using the standard JavaScript error reporting mechanism (including script filename and line number), if <i>fatal</i> is <i>true</i>, immediately terminates script
<tr valign=top><td><b>get_parent</b><td>object<td><tt>js.get_parent(object)
<td>3.14
<td>return the parent of the specified object
<tr valign=top><td><b>get_size</b><td>number<td><tt>js.get_size([object])
<td>3.16
<td>return the size in bytes the object uses in memory (forces GC) 
<tr valign=top><td><b>flatten_string</b><td>void<td><tt>js.flatten_string([string])
<td>3.16
<td>flatten a string, optimizing allocated memory used for concatenated strings
<tr valign=top><td><b>exec</b><td>number<td><tt>js.exec(filename [, startup_dir], <i>object</i> scope [,...])
<td>3.17c
<td>execute a script within the specified scope.  The main difference between this method and <tt>load()</tt> is that scripts called this way can call <tt>exit()</tt> without terminating the caller.  If it does, any <tt>on_exit()</tt> handlers will be evaluated in scripts scope when the script exists. <br>NOTE: to get a child of the current scope, you need to create an object in the current scope. An anonymous object can be created using '<tt>new function(){}</tt>'. <br>NOTE: Use <tt>js.exec.apply()</tt> if you need to pass a variable number of arguments to the executed script.
</table>
<br>
<table border=1 width=100%>
<caption align=left><b><tt>js</tt>
<a name=js_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>version</b><td>string
<td>3.11
<td>JavaScript engine version information (AKA system.js_version)
<tr valign=top><td><b>auto_terminate</b><td>boolean
<td>3.11
<td>set to <i>false</i> to disable the automatic termination of the script upon external request
<tr valign=top><td><b>terminated</b><td>boolean
<td>3.11
<td>termination has been requested (stop execution as soon as possible)
<tr valign=top><td><b>counter</b><td>number
<td>3.16
<td>number of operation callbacks performed in this runtime
<tr valign=top><td><b>time_limit</b><td>number
<td>3.16
<td>maximum number of operation callbacks, used for infinite-loop detection (0=disabled)
<tr valign=top><td><b>yield_interval</b><td>number
<td>3.11
<td>interval of periodic time-slice yields (lower number=higher frequency, 0=disabled)
<tr valign=top><td><b>gc_interval</b><td>number
<td>3.11
<td>interval of periodic garbage collection attempts (lower number=higher frequency, 0=disabled)
<tr valign=top><td><b>gc_attempts</b><td>number
<td>3.11
<td>number of garbage collections attempted in this runtime - <small>READ ONLY</small>
<tr valign=top><td><b>global</b><td>object
<td>3.14
<td>global (top level) object - <small>READ ONLY</small>
<tr valign=top><td><b>exec_path</b><td>string
<td>N/A
<td>full path and filename of JS file executed
<tr valign=top><td><b>exec_file</b><td>string
<td>N/A
<td>JS filename executed (with no path)
<tr valign=top><td><b>exec_dir</b><td>string
<td>N/A
<td>directory of executed JS file
<tr valign=top><td><b>startup_dir</b><td>string
<td>N/A
<td>Either the configured startup directory in SCFG (for externals) or the cwd when jsexec is started
<tr valign=top><td><b>scope</b><td>object
<td>N/A
<td>global scope for this script
<tr valign=top><td><b>load_path_list</b><td>object
<td>N/A
<td>load() search path array.<br>For relative load paths (e.g. not beginning with '/' or '\'), the path is assumed to be a sub-directory of the (configurable) mods or exec directories and is searched accordingly. So, by default, load("somefile.js") will search in this order:<br>mods/load/somefile.js<br>exec/load/somefile.js<br>mods/somefile.js<br>exec/somefile.js<br>
</table>
<h2><a name=system>system object</a>
<br><font size=-1>Global system-related properties and methods</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>system</tt>
<a name=system_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>username</b><td>string<td><tt>system.username(user_number)
<td>3.11
<td>returns name of user in specified user record <i>number</i>, or empty string if not found
<tr valign=top><td><b>alias</b><td>string<td><tt>system.alias(alias)
<td>3.10
<td>returns name of user that matches alias (if found in <tt>ctrl/alias.cfg</tt>)
<tr valign=top><td><b>matchuser</b><td>number<td><tt>system.matchuser(username [,sysop_alias=<tt>true</tt>])
<td>3.10
<td>exact user name matching, returns number of user whose name/alias matches <i>username</i>  or 0 if not found, matches well-known sysop aliases by default
<tr valign=top><td><b>matchuserdata</b><td>number<td><tt>system.matchuserdata(field, data [,usernumber, match_next=<tt>false</tt>])
<td>3.10
<td>search user database for data in a specific field (see <tt>U_*</tt> in <tt>sbbsdefs.js</tt>), returns first matching user record number, optional <i>usernumber</i> specifies user record to skip, or record at which to begin searching if optional <i>match_next</i> is <tt>true</tt>
<tr valign=top><td><b>trashcan</b><td>boolean<td><tt>system.trashcan(basename, find_string)
<td>3.10
<td>search <tt>text/<i>basename</i>.can</tt> for pseudo-regexp
<tr valign=top><td><b>findstr</b><td>boolean<td><tt>system.findstr(path/filename, find_string)
<td>3.10
<td>search any file for pseudo-regexp
<tr valign=top><td><b>zonestr</b><td>string<td><tt>system.zonestr([timezone=<i>local</i>])
<td>3.10
<td>convert time zone integer to string, defaults to system timezone if <i>timezone</i> not specified
<tr valign=top><td><b>timestr</b><td>string<td><tt>system.timestr([time=<i>current</i>])
<td>3.10
<td>convert time_t integer into a time string, defaults to current time if <i>time</i> not specified
<tr valign=top><td><b>datestr</b><td>string<td><tt>system.datestr([time=<i>current</i>])
<td>3.10
<td>convert time_t integer into a date string (in either <tt>MM/DD/YY</tt> or <tt>DD/MM/YY</tt> format), defaults to current date if <i>time</i> not specified. If <i>time</i> is a string in the appropriate format, returns the time_t.
<tr valign=top><td><b>secondstr</b><td>string<td><tt>system.secondstr(seconds)
<td>3.10
<td>convert elapsed time in seconds into a string in <tt>hh:mm:ss</tt> format
<tr valign=top><td><b>spamlog</b><td>boolean<td><tt>system.spamlog([protocol, action, reason, host, ip, to, from])
<td>3.10
<td>log a suspected SPAM attempt
<tr valign=top><td><b>hacklog</b><td>boolean<td><tt>system.hacklog([protocol, user, text, host, ip, port])
<td>3.10
<td>log a suspected hack attempt
<tr valign=top><td><b>filter_ip</b><td>boolean<td><tt>system.filter_ip([protocol, reason, host, ip, username, filename])
<td>3.11
<td>add an IP address (with comment) to an IP filter file. If filename is not specified, the ip.can file is used
<tr valign=top><td><b>get_node</b><td>object<td><tt>system.get_node(node_number)
<td>3.17c
<td>read a node data record all at once (and leaving the record unlocked) returning an object matching the elements of <tt>system.node_list</tt>
<tr valign=top><td><b>get_node_message</b><td>string<td><tt>system.get_node_message(node_number)
<td>3.11
<td>read any messages waiting for the specified node and return in a single string
<tr valign=top><td><b>put_node_message</b><td>boolean<td><tt>system.put_node_message(node_number, message_text)
<td>3.10
<td>send a node a short text message, delivered immediately
<tr valign=top><td><b>get_telegram</b><td>string<td><tt>system.get_telegram(user_number)
<td>3.11
<td>returns any short text messages waiting for the specified user
<tr valign=top><td><b>put_telegram</b><td>boolean<td><tt>system.put_telegram(user_number, message_text)
<td>3.10
<td>sends a user a short text message, delivered immediately or during next logon
<tr valign=top><td><b>notify</b><td>boolean<td><tt>system.notify(user_number, subject [,message_text])
<td>3.18b
<td>notify a user or operator via both email and a short text message about an important event
<tr valign=top><td><b>new_user</b><td>object<td><tt>system.new_user(name/alias [,client object])
<td>3.10
<td>creates a new user record, returns a new <a href=#User>User</a> object representing the new user account, on success.<br>returns an numeric error code on failure (optional <i>client</i> object argument added in v3.15a.  As of 3.16c, the global client object is used if the argument is omitted)
<tr valign=top><td><b>del_user</b><td>boolean<td><tt>system.del_user(user_number)
<td>3.16
<td>delete the specified user account
<tr valign=top><td><b>exec</b><td>number<td><tt>system.exec(command-line)
<td>3.11
<td>executes a native system/shell command-line, returns <i>0</i> on success
<tr valign=top><td><b>popen</b><td>array<td><tt>system.popen(command-line)
<td>3.11
<td>executes a native system/shell command-line, returns array of captured output lines on success (<b>only functional on UNIX systems</b>)
<tr valign=top><td><b>check_syspass</b><td>boolean<td><tt>system.check_syspass(password)
<td>3.11
<td>compares the supplied <i>password</i> against the system password and returns <i>true</i> if it matches
<tr valign=top><td><b>check_name</b><td>boolean<td><tt>system.check_name(name/alias)
<td>3.15
<td>checks that the provided name/alias string is suitable for a new user account, returns <i>true</i> if it is valid
<tr valign=top><td><b>check_pid</b><td>boolean<td><tt>system.check_pid(process-ID)
<td>3.15
<td>checks that the provided process ID is a valid executing process on the system, returns <i>true</i> if it is valid
<tr valign=top><td><b>terminate_pid</b><td>boolean<td><tt>system.terminate_pid(process-ID)
<td>3.15
<td>terminates executing process on the system with the specified process ID, returns <i>true</i> on success
</table>
<br>
<table border=1 width=100%>
<caption align=left><b><tt>system</tt>
<a name=system_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>name</b><td>string
<td>3.10
<td>BBS name
<tr valign=top><td><b>operator</b><td>string
<td>3.10
<td>operator name
<tr valign=top><td><b>operator_available</b><td>boolean
<td>3.18b
<td>operator is available for chat
<tr valign=top><td><b>qwk_id</b><td>string
<td>3.10
<td>system QWK-ID (for QWK packets)
<tr valign=top><td><b>settings</b><td>number
<td>3.10
<td>settings bitfield (see <tt>SYS_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)
<tr valign=top><td><b>inet_addr</b><td>string
<td>3.11
<td>Internet address (host or domain name)
<tr valign=top><td><b>location</b><td>string
<td>3.10
<td>location (city, state)
<tr valign=top><td><b>timezone</b><td>number
<td>3.10
<td>timezone (use <i>system.zonestr()</i> to get string representation)
<tr valign=top><td><b>pwdays</b><td>number
<td>3.10
<td>days between forced user password changes (<tt>0</tt>=<i>never</i>)
<tr valign=top><td><b>min_password_length</b><td>number
<td>3.17c
<td>minimum number of characters in user passwords
<tr valign=top><td><b>max_password_length</b><td>number
<td>3.17c
<td>maximum number of characters in user passwords
<tr valign=top><td><b>deldays</b><td>number
<td>3.10
<td>days to preserve deleted user records, record will not be reused/overwritten during this period
<tr valign=top><td><b>autodel</b><td>number
<td>3.17c
<td>days of user inactivity before auto-deletion (<tt>0</tt>=<i>disabled</i>), N/A to P-exempt users
<tr valign=top><td><b>lastuser</b><td>number
<td>3.11
<td>last user record number in user database (includes deleted and inactive user records)
<tr valign=top><td><b>lastuseron</b><td>string
<td>3.10
<td>name of last user to logoff
<tr valign=top><td><b>freediskspace</b><td>number
<td>3.10
<td>amount of free disk space (in bytes)
<tr valign=top><td><b>freediskspacek</b><td>number
<td>3.10
<td>amount of free disk space (in kilobytes)
<tr valign=top><td><b>nodes</b><td>number
<td>3.10
<td>total number of BBS nodes
<tr valign=top><td><b>lastnode</b><td>number
<td>3.10
<td>last displayable node number
<tr valign=top><td><b>newuser_password</b><td>string
<td>3.10
<td>new user password
<tr valign=top><td><b>newuser_magic_word</b><td>string
<td>3.10
<td>new user magic word
<tr valign=top><td><b>newuser_level</b><td>number
<td>3.10
<td>new user level
<tr valign=top><td><b>newuser_flags1</b><td>number
<td>3.10
<td>new user flag set #1
<tr valign=top><td><b>newuser_flags2</b><td>number
<td>3.10
<td>new user flag set #2
<tr valign=top><td><b>newuser_flags3</b><td>number
<td>3.10
<td>new user flag set #3
<tr valign=top><td><b>newuser_flags4</b><td>number
<td>3.10
<td>new user flag set #4
<tr valign=top><td><b>newuser_restrictions</b><td>number
<td>3.10
<td>new user restriction flags
<tr valign=top><td><b>newuser_exemptions</b><td>number
<td>3.10
<td>new user exemption flags
<tr valign=top><td><b>newuser_credits</b><td>number
<td>3.10
<td>new user credits
<tr valign=top><td><b>newuser_minutes</b><td>number
<td>3.10
<td>new user extra minutes
<tr valign=top><td><b>newuser_command_shell</b><td>string
<td>3.10
<td>new user command shell
<tr valign=top><td><b>newuser_editor</b><td>string
<td>3.10
<td>new user external editor
<tr valign=top><td><b>newuser_settings</b><td>number
<td>3.10
<td>new user settings
<tr valign=top><td><b>newuser_download_protocol</b><td>string
<td>3.10
<td>new user file transfer protocol (command key)
<tr valign=top><td><b>newuser_expiration_days</b><td>number
<td>3.10
<td>new user expiration days
<tr valign=top><td><b>newuser_questions</b><td>number
<td>3.10
<td>new user questions bitfield (see <tt>UQ_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)
<tr valign=top><td><b>expired_level</b><td>number
<td>3.10
<td>expired user level
<tr valign=top><td><b>expired_flags1</b><td>number
<td>3.10
<td>expired user flag set #1
<tr valign=top><td><b>expired_flags2</b><td>number
<td>3.10
<td>expired user flag set #2
<tr valign=top><td><b>expired_flags3</b><td>number
<td>3.10
<td>expired user flag set #3
<tr valign=top><td><b>expired_flags4</b><td>number
<td>3.10
<td>expired user flag set #4
<tr valign=top><td><b>expired_restrictions</b><td>number
<td>3.10
<td>expired user restriction flags
<tr valign=top><td><b>expired_exemptions</b><td>number
<td>3.10
<td>expired user exemption flags
<tr valign=top><td><b>node_dir</b><td>string
<td>3.10
<td>node directory
<tr valign=top><td><b>ctrl_dir</b><td>string
<td>3.10
<td>control file directory
<tr valign=top><td><b>data_dir</b><td>string
<td>3.10
<td>data file directory
<tr valign=top><td><b>text_dir</b><td>string
<td>3.10
<td>text file directory
<tr valign=top><td><b>temp_dir</b><td>string
<td>3.10
<td>temporary file directory
<tr valign=top><td><b>exec_dir</b><td>string
<td>3.10
<td>executable file directory
<tr valign=top><td><b>mods_dir</b><td>string
<td>3.10
<td>modified modules directory (optional)
<tr valign=top><td><b>logs_dir</b><td>string
<td>3.10
<td>log file directory
<tr valign=top><td><b>devnull</b><td>string
<td>3.11
<td>platform-specific "null" device filename
<tr valign=top><td><b>temp_path</b><td>string
<td>3.12
<td>platform-specific temporary file directory
<tr valign=top><td><b>cmd_shell</b><td>string
<td>3.14
<td>platform-specific command processor/shell
<tr valign=top><td><b>clock_ticks</b><td>number
<td>3.11
<td>amount of elapsed processor time in clock 'ticks'
<tr valign=top><td><b>clock_ticks_per_second</b><td>number
<td>3.11
<td>number of clock ticks per second
<tr valign=top><td><b>timer</b><td>number
<td>3.14
<td>high-resolution timer, in seconds (fractional seconds supported)
<tr valign=top><td><b>local_host_name</b><td>string
<td>3.11
<td>private host name that uniquely identifies this system on the local network
<tr valign=top><td><b>host_name</b><td>string
<td>N/A
<td>public host name that uniquely identifies this system on the Internet (usually the same as <i>system.inet_addr</i>)
<tr valign=top><td><b>socket_lib</b><td>string
<td>N/A
<td>socket library version information
<tr valign=top><td><b>uptime</b><td>number
<td>N/A
<td>time/date system was brought online (in time_t format)
<tr valign=top><td><b>full_version</b><td>string
<td>N/A
<td>Synchronet full version information (e.g. '3.10k Beta Debug')
<tr valign=top><td><b>compiled_when</b><td>string
<td>N/A
<td>date and time compiled
<tr valign=top><td><b>version</b><td>string
<td>N/A
<td>Synchronet version number (e.g. '3.10')
<tr valign=top><td><b>revision</b><td>string
<td>N/A
<td>Synchronet revision letter (e.g. 'k')
<tr valign=top><td><b>beta_version</b><td>string
<td>N/A
<td>Synchronet alpha/beta designation (e.g. ' beta')
<tr valign=top><td><b>version_notice</b><td>string
<td>N/A
<td>Synchronet version notice (includes version and platform)
<tr valign=top><td><b>version_num</b><td>number
<td>N/A
<td>Synchronet version number in decimal (e.g. 31301 for v3.13b)
<tr valign=top><td><b>version_hex</b><td>number
<td>N/A
<td>Synchronet version number in hexadecimal (e.g. 0x31301 for v3.13b)
<tr valign=top><td><b>platform</b><td>string
<td>N/A
<td>platform description (e.g. 'Win32', 'Linux', 'FreeBSD')
<tr valign=top><td><b>architecture</b><td>string
<td>N/A
<td>architecture description (e.g. 'i386', 'i686', 'x86_64')
<tr valign=top><td><b>msgbase_lib</b><td>string
<td>N/A
<td>message base library version information
<tr valign=top><td><b>compiled_with</b><td>string
<td>N/A
<td>compiler used to build Synchronet
<tr valign=top><td><b>copyright</b><td>string
<td>N/A
<td>Synchronet copyright display
<tr valign=top><td><b>js_version</b><td>string
<td>N/A
<td>JavaScript engine version information
<tr valign=top><td><b>os_version</b><td>string
<td>N/A
<td>operating system version information
<tr valign=top><td><b>fido_addr_list</b><td>object
<td>N/A
<td>array of FidoNet Technology Network (FTN) addresses associated with this system
</table>
<h2><a name=system.stats>system.stats object</a>
<br><font size=-1>System statistics</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>system.stats</tt>
<a name=system.stats_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>total_logons</b><td>number
<td>3.10
<td>total logons
<tr valign=top><td><b>logons_today</b><td>number
<td>3.10
<td>logons today
<tr valign=top><td><b>total_timeon</b><td>number
<td>3.10
<td>total time used
<tr valign=top><td><b>timeon_today</b><td>number
<td>3.10
<td>time used today
<tr valign=top><td><b>total_files</b><td>number
<td>3.10
<td>total files in file bases
<tr valign=top><td><b>files_uploaded_today</b><td>number
<td>3.10
<td>files uploaded today
<tr valign=top><td><b>bytes_uploaded_today</b><td>number
<td>3.10
<td>bytes uploaded today
<tr valign=top><td><b>files_downloaded_today</b><td>number
<td>3.10
<td>files downloaded today
<tr valign=top><td><b>bytes_downloaded_today</b><td>number
<td>3.10
<td>bytes downloaded today
<tr valign=top><td><b>total_messages</b><td>number
<td>3.10
<td>total messages in message bases
<tr valign=top><td><b>messages_posted_today</b><td>number
<td>3.10
<td>messages posted today
<tr valign=top><td><b>total_email</b><td>number
<td>3.10
<td>total messages in mail base
<tr valign=top><td><b>email_sent_today</b><td>number
<td>3.10
<td>email sent today
<tr valign=top><td><b>total_feedback</b><td>number
<td>3.10
<td>total feedback messages waiting
<tr valign=top><td><b>feedback_sent_today</b><td>number
<td>3.10
<td>feedback sent today
<tr valign=top><td><b>total_users</b><td>number
<td>3.10
<td>total user records (does not include deleted or inactive user records)
<tr valign=top><td><b>new_users_today</b><td>number
<td>3.10
<td>new users today
</table>
<h2><a name=system.node_list>system.node_list array</a>
<br><font size=-1>BBS node listing</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>system.node_list</tt>
<a name=system.node_list_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>status</b><td>number
<td>3.10
<td>status (see <tt>nodedefs.js</tt> for valid values)
<tr valign=top><td><b>errors</b><td>number
<td>3.10
<td>error counter
<tr valign=top><td><b>action</b><td>number
<td>3.10
<td>current user action (see <tt>nodedefs.js</tt>)
<tr valign=top><td><b>useron</b><td>number
<td>3.10
<td>current user number
<tr valign=top><td><b>connection</b><td>number
<td>3.10
<td>connection speed (<tt>0xffff</tt> = Telnet or RLogin)
<tr valign=top><td><b>misc</b><td>number
<td>3.10
<td>miscellaneous bitfield (see <tt>nodedefs.js</tt>)
<tr valign=top><td><b>aux</b><td>number
<td>3.10
<td>auxillary value
<tr valign=top><td><b>extaux</b><td>number
<td>3.10
<td>extended auxillary value
<tr valign=top><td><b>dir</b><td>string
<td>3.15
<td>node directory
</table>
<h2><a name=server>server object</a>
<br><font size=-1>Server-specifc properties</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>server</tt>
<a name=server_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>version</b><td>string
<td>3.10
<td>server name and version number
<tr valign=top><td><b>version_detail</b><td>string
<td>3.10
<td>detailed version/build information
<tr valign=top><td><b>interface_ip_address</b><td>string
<td>3.11
<td>First bound IPv4 address (<tt>0.0.0.0</tt> = <i>ANY</i>) (obsolete since 3.17, see interface_ip_addr_list)
<tr valign=top><td><b>options</b><td>number
<td>3.11
<td>bit-field of server-specific startup options
<tr valign=top><td><b>clients</b><td>number
<td>3.11
<td>number of active clients (if available)
<tr valign=top><td><b>interface_ip_addr_list</b><td>object
<td>N/A
<td>Array of IP addresses of bound network interface (<tt>0.0.0.0</tt> = <i>ANY</i>)
</table>
<h2><a name=client>client object</a>
<br><font size=-1>Represents a TCP/IP client session</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>client</tt>
<a name=client_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>ip_address</b><td>string
<td>3.10
<td>client's IPv4 or IPv6 address
<tr valign=top><td><b>host_name</b><td>string
<td>3.10
<td>client's host name (up to 64 characters)
<tr valign=top><td><b>port</b><td>number
<td>3.10
<td>client's TCP or UDP port number
<tr valign=top><td><b>connect_time</b><td>number
<td>3.10
<td>date/time of initial connection (in time_t format)
<tr valign=top><td><b>protocol</b><td>string
<td>3.10
<td>protocol/service name (e.g. 'Telnet', 'FTP', etc.)
<tr valign=top><td><b>user_name</b><td>string
<td>3.10
<td>user's name/alias
<tr valign=top><td><b>user_number</b><td>number
<td>3.17c
<td>user's number (non-zero if logged in)
<tr valign=top><td><b>socket</b><td>object
<td>N/A
<td>instance of <a href=#Socket>Socket class</a> representing client's TCP/IP connection
</table>
<h2><a name=user>user object</a>
<br><font size=-1>Instance of <i>User</i> class, representing current user online</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<p>To create a new user object: <tt>var u = new User;</tt> or: <tt>var u = new User(<i>number</i>);</tt></p>
<table border=1 width=100%>
<caption align=left><b><tt>user</tt>
<a name=user_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>compare_ars</b><td>boolean<td><tt>user.compare_ars(string ars)
<td>3.10
<td>Verify user meets access requirements string<br>Note: For the current user of the terminal server, use <tt>bbs.compare_ars()</tt> instead.
<tr valign=top><td><b>adjust_credits</b><td>boolean<td><tt>user.adjust_credits(count)
<td>3.14
<td>Adjust user's credits by <i>count</i> (negative to subtract)
<tr valign=top><td><b>adjust_minutes</b><td>boolean<td><tt>user.adjust_minutes(count)
<td>3.14
<td>Adjust user's extra minutes <i>count</i> (negative to subtract)
<tr valign=top><td><b>posted_message</b><td>boolean<td><tt>user.posted_message([count])
<td>3.14
<td>Adjust user's posted-messages statistics by <i>count</i> (default: 1) (negative to subtract)
<tr valign=top><td><b>sent_email</b><td>boolean<td><tt>user.sent_email([count] [,bool feedback])
<td>3.14
<td>Adjust user's email/feedback-sent statistics by <i>count</i> (default: 1) (negative to subtract)
<tr valign=top><td><b>uploaded_file</b><td>boolean<td><tt>user.uploaded_file([bytes] [,files])
<td>3.14
<td>Adjust user's files/bytes-uploaded statistics
<tr valign=top><td><b>downloaded_file</b><td>boolean<td><tt>user.downloaded_file([dir-code] [file path | name] [bytes] [,file-count])
<td>3.18
<td>Handle the full or partial successful download of a file.<br>Adjust user's files/bytes-downloaded statistics and credits, file's stats, system's stats, and uploader's stats and credits.
<tr valign=top><td><b>get_time_left</b><td>number<td><tt>user.get_time_left(start_time)
<td>3.14b
<td>Returns the user's available remaining time online, in seconds,<br>based on the passed <i>start_time</i> value (in time_t format)<br>Note: this method does not account for pending forced timed eventsNote: for the pre-defined user object on the BBS, you almost certainly want bbs.get_time_left() instead.
</table>
<br>
<table border=1 width=100%>
<caption align=left><b><tt>user</tt>
<a name=user_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>number</b><td>number
<td>3.10
<td>record number (1-based)
<tr valign=top><td><b>alias</b><td>string
<td>3.10
<td>alias/name
<tr valign=top><td><b>name</b><td>string
<td>3.10
<td>real name
<tr valign=top><td><b>handle</b><td>string
<td>3.10
<td>chat handle
<tr valign=top><td><b>ip_address</b><td>string
<td>3.10
<td>IP address last logged on from
<tr valign=top><td><b>note</b><td>string
<td>3.10
<td>Sysop note (AKA ip_address on 3.16 and before)
<tr valign=top><td><b>host_name</b><td>string
<td>3.10
<td>host name last logged on from
<tr valign=top><td><b>computer</b><td>string
<td>3.10
<td>AKA host_name
<tr valign=top><td><b>comment</b><td>string
<td>3.10
<td>sysop's comment
<tr valign=top><td><b>netmail</b><td>string
<td>3.10
<td>external e-mail address
<tr valign=top><td><b>email</b><td>string
<td>3.10
<td>local Internet e-mail address	- <small>READ ONLY</small>
<tr valign=top><td><b>address</b><td>string
<td>3.10
<td>street address
<tr valign=top><td><b>location</b><td>string
<td>3.10
<td>location (e.g. city, state)
<tr valign=top><td><b>zipcode</b><td>string
<td>3.10
<td>zip/postal code
<tr valign=top><td><b>phone</b><td>string
<td>3.10
<td>phone number
<tr valign=top><td><b>birthdate</b><td>string
<td>3.10
<td>birth date in either MM/DD/YY or DD/MM/YY format depending on system configuration
<tr valign=top><td><b>age</b><td>number
<td>3.10
<td>calculated age in years - <small>READ ONLY</small>
<tr valign=top><td><b>connection</b><td>string
<td>3.10
<td>connection type (protocol)
<tr valign=top><td><b>modem</b><td>string
<td>3.10
<td>AKA connection
<tr valign=top><td><b>screen_rows</b><td>number
<td>3.10
<td>terminal rows (lines)
<tr valign=top><td><b>gender</b><td>string
<td>3.10
<td>gender type (e.g. M or F)
<tr valign=top><td><b>cursub</b><td>string
<td>3.10
<td>current/last message sub-board (internal code)
<tr valign=top><td><b>curdir</b><td>string
<td>3.10
<td>current/last file directory (internal code)
<tr valign=top><td><b>curxtrn</b><td>string
<td>3.10
<td>current/last external program (internal code) run
<tr valign=top><td><b>editor</b><td>string
<td>3.10
<td>external message editor (internal code) or <i>blank</i> if none
<tr valign=top><td><b>command_shell</b><td>string
<td>3.10
<td>command shell (internal code)
<tr valign=top><td><b>settings</b><td>number
<td>3.10
<td>settings bitfield - see <tt>USER_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions
<tr valign=top><td><b>qwk_settings</b><td>number
<td>3.10
<td>QWK packet settings bitfield - see <tt>QWK_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions
<tr valign=top><td><b>chat_settings</b><td>number
<td>3.10
<td>chat settings bitfield - see <tt>CHAT_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions
<tr valign=top><td><b>temp_file_ext</b><td>string
<td>3.10
<td>temporary file type (extension)
<tr valign=top><td><b>new_file_time</b><td>number
<td>3.11
<td>new file scan date/time (time_t format)
<tr valign=top><td><b>download_protocol</b><td>string
<td>3.10
<td>file transfer protocol (command key)
<tr valign=top><td><b>logontime</b><td>number
<td>3.10
<td>logon time (time_t format)
<tr valign=top><td><b>cached</b><td>boolean
<td>3.14
<td>record is currently cached in memory
<tr valign=top><td><b>is_sysop</b><td>boolean
<td>3.15
<td>user has a System Operator's security level
</table>
<h2><a name=user.stats>user.stats object</a>
<br><font size=-1>User statistics (all <small>READ ONLY</small>)</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>user.stats</tt>
<a name=user.stats_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>laston_date</b><td>number
<td>3.10
<td>date of previous logon (time_t format)
<tr valign=top><td><b>firston_date</b><td>number
<td>3.10
<td>date of first logon (time_t format)
<tr valign=top><td><b>total_logons</b><td>number
<td>3.10
<td>total number of logons
<tr valign=top><td><b>logons_today</b><td>number
<td>3.10
<td>total logons today
<tr valign=top><td><b>total_timeon</b><td>number
<td>3.10
<td>total time used (in minutes)
<tr valign=top><td><b>timeon_today</b><td>number
<td>3.10
<td>time used today
<tr valign=top><td><b>timeon_last_logon</b><td>number
<td>3.10
<td>time used last session
<tr valign=top><td><b>total_posts</b><td>number
<td>3.10
<td>total messages posted
<tr valign=top><td><b>total_emails</b><td>number
<td>3.10
<td>total e-mails sent
<tr valign=top><td><b>total_feedbacks</b><td>number
<td>3.10
<td>total feedback messages sent
<tr valign=top><td><b>email_today</b><td>number
<td>3.10
<td>e-mail sent today
<tr valign=top><td><b>posts_today</b><td>number
<td>3.10
<td>messages posted today
<tr valign=top><td><b>bytes_uploaded</b><td>number
<td>3.10
<td>total bytes uploaded
<tr valign=top><td><b>files_uploaded</b><td>number
<td>3.10
<td>total files uploaded
<tr valign=top><td><b>bytes_downloaded</b><td>number
<td>3.10
<td>total bytes downloaded
<tr valign=top><td><b>files_downloaded</b><td>number
<td>3.10
<td>total files downloaded
<tr valign=top><td><b>leech_attempts</b><td>number
<td>3.10
<td>suspected leech downloads
<tr valign=top><td><b>mail_waiting</b><td>number
<td>3.12
<td>number of e-mail messages currently waiting
<tr valign=top><td><b>mail_pending</b><td>number
<td>3.12
<td>number of e-mail messages sent, currently pending deletion
</table>
<h2><a name=user.security>user.security object</a>
<br><font size=-1>User security settings</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>user.security</tt>
<a name=user.security_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>password</b><td>string
<td>3.10
<td>password
<tr valign=top><td><b>password_date</b><td>number
<td>3.10
<td>date password last modified (time_t format)
<tr valign=top><td><b>level</b><td>number
<td>3.10
<td>security level (0-99)
<tr valign=top><td><b>flags1</b><td>number
<td>3.10
<td>flag set #1 (bitfield) can use +/-[A-?] notation
<tr valign=top><td><b>flags2</b><td>number
<td>3.10
<td>flag set #2 (bitfield) can use +/-[A-?] notation
<tr valign=top><td><b>flags3</b><td>number
<td>3.10
<td>flag set #3 (bitfield) can use +/-[A-?] notation
<tr valign=top><td><b>flags4</b><td>number
<td>3.10
<td>flag set #4 (bitfield) can use +/-[A-?] notation
<tr valign=top><td><b>exemptions</b><td>number
<td>3.10
<td>exemption flags (bitfield) can use +/-[A-?] notation
<tr valign=top><td><b>restrictions</b><td>number
<td>3.10
<td>restriction flags (bitfield) can use +/-[A-?] notation
<tr valign=top><td><b>credits</b><td>number
<td>3.10
<td>credits
<tr valign=top><td><b>free_credits</b><td>number
<td>3.10
<td>free credits (for today only)
<tr valign=top><td><b>minutes</b><td>number
<td>3.10
<td>extra minutes (time bank)
<tr valign=top><td><b>extra_time</b><td>number
<td>3.10
<td>extra minutes (for today only)
<tr valign=top><td><b>expiration_date</b><td>number
<td>3.10
<td>expiration date/time (time_t format)
</table>
<h2><a name=user.limits>user.limits object</a>
<br><font size=-1>User limitations based on security level (all <small>READ ONLY</small>)</font>
<font size=-1> - introduced in v3.11</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>user.limits</tt>
<a name=user.limits_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>time_per_logon</b><td>number
<td>3.11
<td>time (in minutes) per logon
<tr valign=top><td><b>time_per_day</b><td>number
<td>3.11
<td>time (in minutes) per day
<tr valign=top><td><b>logons_per_day</b><td>number
<td>3.11
<td>logons per day
<tr valign=top><td><b>lines_per_message</b><td>number
<td>3.11
<td>lines per message (post or email)
<tr valign=top><td><b>email_per_day</b><td>number
<td>3.11
<td>email sent per day
<tr valign=top><td><b>posts_per_day</b><td>number
<td>3.11
<td>messages posted per day
<tr valign=top><td><b>free_credits_per_day</b><td>number
<td>3.11
<td>free credits given per day
</table>
<h2><a name=bbs>bbs object</a>
<br><font size=-1>Controls the Telnet/SSH/RLogin BBS experience</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>bbs</tt>
<a name=bbs_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>atcode</b><td>string<td><tt>bbs.atcode(code_string)
<td>3.10
<td>returns @-code value, specified <i>code</i> string does not include @ character delimiters
<tr valign=top><td><b>text</b><td>string<td><tt>bbs.text(line_number)
<td>3.10
<td>returns specified text string from text.dat
<tr valign=top><td><b>replace_text</b><td>boolean<td><tt>bbs.replace_text(line_number, text)
<td>3.10
<td>replaces specified text string in memory
<tr valign=top><td><b>revert_text</b><td>boolean<td><tt>bbs.revert_text([line_number=<i>all</i>])
<td>3.10
<td>reverts specified text string to original text string; if <i>line_number</i> unspecified, reverts all text lines
<tr valign=top><td><b>load_text</b><td>boolean<td><tt>bbs.load_text(base_filename)
<td>3.10
<td>load an alternate text.dat from ctrl directory, automatically appends '.dat' to basefilename
<tr valign=top><td><b>newuser</b><td>void<td><tt>bbs.newuser()
<td>3.10
<td>interactive new user procedure
<tr valign=top><td><b>login</b><td>boolean<td><tt>bbs.login(user_name [,password_prompt] [,user_password] [,system_password])
<td>3.10
<td>login with <i>user_name</i>, displaying <i>password_prompt</i> for user's password (if required), optionally supplying the user's password and the system password as arguments so as to not be prompted
<tr valign=top><td><b>logon</b><td>boolean<td><tt>bbs.logon()
<td>3.10
<td>interactive logon procedure
<tr valign=top><td><b>logoff</b><td>void<td><tt>bbs.logoff([prompt=<i>true</i>])
<td>3.15
<td>interactive logoff procedure, pass <i>false</i> for <i>prompt</i> argument to avoid yes/no prompt
<tr valign=top><td><b>logout</b><td>void<td><tt>bbs.logout()
<td>3.10
<td>non-interactive logout procedure
<tr valign=top><td><b>hangup</b><td>void<td><tt>bbs.hangup()
<td>3.10
<td>hangup (disconnect) immediately
<tr valign=top><td><b>nodesync</b><td>void<td><tt>bbs.nodesync([clearline=<i>false</i>])
<td>3.10
<td>synchronize with node database, checks for messages, interruption, etc. (AKA node_sync), clears the current console line if there's a message to print when <i>clearline</i> is <i>true</i>.
<tr valign=top><td><b>auto_msg</b><td>void<td><tt>bbs.auto_msg()
<td>3.10
<td>read/create system's auto-message
<tr valign=top><td><b>time_bank</b><td>void<td><tt>bbs.time_bank()
<td>3.10
<td>enter the time banking system
<tr valign=top><td><b>qwk_sec</b><td>void<td><tt>bbs.qwk_sec()
<td>3.10
<td>enter the QWK message packet upload/download/config section
<tr valign=top><td><b>text_sec</b><td>void<td><tt>bbs.text_sec()
<td>3.10
<td>enter the text files section
<tr valign=top><td><b>xtrn_sec</b><td>void<td><tt>bbs.xtrn_sec([section])
<td>3.10
<td>enter the external programs section (or go directly to the specified <i>section</i>)
<tr valign=top><td><b>xfer_policy</b><td>void<td><tt>bbs.xfer_policy()
<td>3.10
<td>display the file transfer policy
<tr valign=top><td><b>batch_menu</b><td>void<td><tt>bbs.batch_menu()
<td>3.10
<td>enter the batch file transfer menu
<tr valign=top><td><b>batch_download</b><td>boolean<td><tt>bbs.batch_download()
<td>3.10
<td>start a batch download
<tr valign=top><td><b>batch_add_list</b><td>void<td><tt>bbs.batch_add_list(list_filename)
<td>3.10
<td>add file list to batch download queue
<tr valign=top><td><b>send_file</b><td>boolean<td><tt>bbs.send_file(filename [,protocol] [,description] [,autohang=true])
<td>3.14
<td>send specified filename (complete path) to user via user-prompted (or optionally specified) protocol.<br>The optional <i>description</i> string is used for logging purposes.<br>When <i>autohang=true</i>, disconnect after transfer based on user's default setting.
<tr valign=top><td><b>receive_file</b><td>boolean<td><tt>bbs.receive_file(filename [,protocol] [,autohang=true])
<td>3.14
<td>received specified filename (complete path) from user via user-prompted (or optionally specified) protocol.<br>When <i>autohang=true</i>, disconnect after transfer based on user's default setting.
<tr valign=top><td><b>temp_xfer</b><td>void<td><tt>bbs.temp_xfer()
<td>3.10
<td>enter the temporary file tranfer menu
<tr valign=top><td><b>user_sync</b><td>void<td><tt>bbs.user_sync()
<td>3.10
<td>read the current user data from the database
<tr valign=top><td><b>user_config</b><td>void<td><tt>bbs.user_config()
<td>3.10
<td>enter the user settings configuration menu
<tr valign=top><td><b>sys_info</b><td>void<td><tt>bbs.sys_info()
<td>3.10
<td>display system information
<tr valign=top><td><b>sub_info</b><td>void<td><tt>bbs.sub_info([sub-board=<i>current</i>])
<td>3.10
<td>display message sub-board information (current <i>sub-board</i>, if unspecified)
<tr valign=top><td><b>dir_info</b><td>void<td><tt>bbs.dir_info([directory=<i>current</i>])
<td>3.10
<td>display file directory information (current <i>directory</i>, if unspecified)
<tr valign=top><td><b>user_info</b><td>void<td><tt>bbs.user_info()
<td>3.10
<td>display current user information
<tr valign=top><td><b>ver</b><td>void<td><tt>bbs.ver()
<td>3.10
<td>display software version information
<tr valign=top><td><b>sys_stats</b><td>void<td><tt>bbs.sys_stats()
<td>3.10
<td>display system statistics
<tr valign=top><td><b>node_stats</b><td>void<td><tt>bbs.node_stats([node_number=<i>current</i>])
<td>3.10
<td>display current (or specified) node statistics
<tr valign=top><td><b>list_users</b><td>void<td><tt>bbs.list_users([mode=<tt>UL_ALL</tt>])
<td>3.10
<td>display user list(see <tt>UL_*</tt> in <tt>sbbsdefs.js</tt> for valid <i>mode</i> values)
<tr valign=top><td><b>edit_user</b><td>void<td><tt>bbs.edit_user([user_number=<i>current</i>])
<td>3.10
<td>enter the user editor
<tr valign=top><td><b>change_user</b><td>void<td><tt>bbs.change_user()
<td>3.10
<td>change to a different user
<tr valign=top><td><b>list_logons</b><td>void<td><tt>bbs.list_logons([arguments])
<td>3.10
<td>display the logon list (optionally passing arguments to the logon list module)
<tr valign=top><td><b>read_mail</b><td>void<td><tt>bbs.read_mail([which=<tt>MAIL_YOUR</tt>] [,user_number=<i>current</i>] [,loadmail_mode=<tt>0</tt>])
<td>3.10
<td>read private e-mail(see <tt>MAIL_*</tt> in <tt>sbbsdefs.js</tt> for valid <i>which</i> values)
<tr valign=top><td><b>email</b><td>boolean<td><tt>bbs.email(to_user_number [,mode=<tt>WM_EMAIL</tt>] [,top=<i>none</i>] [,subject=<i>none</i>] [,object reply_header])
<td>3.10
<td>send private e-mail to a local user (<i>reply_header</i> added in v3.17c)
<tr valign=top><td><b>netmail</b><td>boolean<td><tt>bbs.netmail([string address or array of addresses] [,mode=<tt>WM_NONE</tt>] [,subject=<i>none</i>] [,object reply_header])
<td>3.10
<td>send private netmail (<i>reply_header</i> added in v3.17c, <i>array of addresses</i> added in v3.18a)
<tr valign=top><td><b>bulk_mail</b><td>void<td><tt>bbs.bulk_mail([ars])
<td>3.10
<td>send bulk private e-mail, if <i>ars</i> not specified, prompt for destination users
<tr valign=top><td><b>upload_file</b><td>boolean<td><tt>bbs.upload_file([directory=<i>current</i>])
<td>3.10
<td>upload file to file directory specified by number or internal code
<tr valign=top><td><b>bulk_upload</b><td>boolean<td><tt>bbs.bulk_upload([directory=<i>current</i>])
<td>3.10
<td>add files (already in local storage path) to file directory specified by number or internal code
<tr valign=top><td><b>resort_dir</b><td>boolean<td><tt>bbs.resort_dir([directory=<i>current</i>])
<td>3.10
<td>re-sort the file directory specified by number or internal code)
<tr valign=top><td><b>list_files</b><td>number<td><tt>bbs.list_files([directory=<i>current</i>] [,filespec=<tt>"*.*"</tt> or search_string] [,mode=<tt>FL_NONE</tt>])
<td>3.10
<td>list files in the specified file directory, optionally specifying a file specification (wildcards) or a description search string, and <i>mode</i> (bitfield)
<tr valign=top><td><b>list_file_info</b><td>number<td><tt>bbs.list_file_info([directory=<i>current</i>] [,filespec=<tt>"*.*"</tt>] [,mode=<tt>FI_INFO</tt>])
<td>3.10
<td>list extended file information for files in the specified file directory
<tr valign=top><td><b>post_msg</b><td>boolean<td><tt>bbs.post_msg([sub-board=<i>current</i>] [,mode=<tt>WM_NONE</tt>] [,object reply_header])
<td>3.13
<td>post a message in the specified message sub-board (number or internal code) with optional <i>mode</i> (bitfield)<br>If <i>reply_header</i> is specified (a header object returned from <i>MsgBase.get_msg_header()</i>), that header will be used for the in-reply-to header fields.
<tr valign=top><td><b>show_msg</b><td>boolean<td><tt>bbs.show_msg(object header [,mode=<tt>P_NONE</tt>] )
<td>3.17c
<td>show a message's header and body (text) with optional print <i>mode</i> (bitfield)<br><i>header</i> must be a header object returned from <i>MsgBase.get_msg_header()</i>)
<tr valign=top><td><b>show_msg_header</b><td>void<td><tt>bbs.show_msg_header(object header [,subject] [,from] [,to])
<td>3.17c
<td>show a message's header (only)<br><i>header</i> must be a header object returned from <i>MsgBase.get_msg_header()</i>)
<tr valign=top><td><b>download_msg_attachments</b><td>void<td><tt>bbs.download_msg_attachments(object header)
<td>3.17c
<td>prompt the user to download each of the message's file attachments (if there are any)<br><i>header</i> must be a header object returned from <i>MsgBase.get_msg_header()</i>)
<tr valign=top><td><b>change_msg_attr</b><td>number<td><tt>bbs.change_msg_attr(object header)
<td>3.17c
<td>prompt the user to modify the specified message header attributes
<tr valign=top><td><b>cfg_msg_scan</b><td>void<td><tt>bbs.cfg_msg_scan([type=<tt>SCAN_CFG_NEW</tt>])
<td>3.10
<td>configure message scan (<i>type</i> is either <tt>SCAN_CFG_NEW</tt> or <tt>SCAN_CFG_TOYOU</tt>)
<tr valign=top><td><b>cfg_msg_ptrs</b><td>void<td><tt>bbs.cfg_msg_ptrs()
<td>3.10
<td>change message scan pointer values
<tr valign=top><td><b>reinit_msg_ptrs</b><td>void<td><tt>bbs.reinit_msg_ptrs()
<td>3.10
<td>re-initialize new message scan pointers
<tr valign=top><td><b>scan_subs</b><td>void<td><tt>bbs.scan_subs([mode=<tt>SCAN_NEW</tt>] [,all=<tt>false</tt>])
<td>3.10
<td>scan sub-boards for messages
<tr valign=top><td><b>scan_dirs</b><td>void<td><tt>bbs.scan_dirs([mode=<tt>FL_NONE</tt>] [,all=<tt>false</tt>])
<td>3.10
<td>scan directories for files
<tr valign=top><td><b>scan_msgs</b><td>boolean<td><tt>bbs.scan_msgs([sub-board=<i>current</i>] [,mode=<tt>SCAN_READ</tt>] [,find])
<td>3.10
<td>scan messages in the specified message sub-board (number or internal code), optionally search for 'find' string (AKA scan_posts)
<tr valign=top><td><b>list_msgs</b><td>number<td><tt>bbs.list_msgs([sub-board=<i>current</i>] [,mode=<tt>SCAN_INDEX</tt>] [,message_number=<tt>0</tt>] [,find])
<td>3.14
<td>list messages in the specified message sub-board (number or internal code), optionally search for 'find' string, returns number of messages listed
<tr valign=top><td><b>menu</b><td>boolean<td><tt>bbs.menu(base_filename [,mode=<tt>P_NONE</tt>] [,object scope])
<td>3.10
<td>display a menu file from the text/menu directory.<br>See <tt>P_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> flags.<br>When <i>scope</i> is specified, <tt>@JS:property@</tt> codes will expand the referenced property names.<br>To display a randomly-chosen menu file, including wild-card (* or ?) characters in the <tt>base_filename</tt>.
<tr valign=top><td><b>menu_exists</b><td>boolean<td><tt>bbs.menu_exists(base_filename)
<td>3.17
<td>returns true if the referenced menu file exists (i.e. in the text/menu directory)
<tr valign=top><td><b>log_key</b><td>boolean<td><tt>bbs.log_key(key [,comma=<tt>false</tt>])
<td>3.10
<td>log key to node.log (comma optional)
<tr valign=top><td><b>log_str</b><td>boolean<td><tt>bbs.log_str(text)
<td>3.10
<td>log string to node.log
<tr valign=top><td><b>finduser</b><td>number<td><tt>bbs.finduser(username_or_number)
<td>3.10
<td>find user name (partial name support), interactive
<tr valign=top><td><b>trashcan</b><td>boolean<td><tt>bbs.trashcan(base_filename, search_string)
<td>3.10
<td>search file for pseudo-regexp (search string) in trashcan file (text/base_filename.can)
<tr valign=top><td><b>exec</b><td>number<td><tt>bbs.exec(cmdline [,mode=<tt>EX_NONE</tt>] [,startup_dir])
<td>3.10
<td>execute a program, optionally changing current directory to <i>startup_dir</i> (see <tt>EX_*</tt> in <tt>sbbsdefs.js</tt> for valid <i>mode</i> flags.)
<tr valign=top><td><b>exec_xtrn</b><td>boolean<td><tt>bbs.exec_xtrn(xtrn_number_or_code)
<td>3.10
<td>execute external program by number or internal code
<tr valign=top><td><b>user_event</b><td>boolean<td><tt>bbs.user_event(event_type)
<td>3.10
<td>execute user event by event type (see <tt>EVENT_*</tt> in <tt>sbbsdefs.js</tt> for valid values)
<tr valign=top><td><b>telnet_gate</b><td>void<td><tt>bbs.telnet_gate(address [,mode=<tt>TG_NONE</tt>])
<td>3.10
<td>external Telnet gateway (see <tt>TG_*</tt> in <tt>sbbsdefs.js</tt> for valid <i>mode</i> flags.)
<tr valign=top><td><b>rlogin_gate</b><td>void<td><tt>bbs.rlogin_gate(address [,client-user-name=<tt>user.alias</tt>, server-user-name=<tt>user.name</tt>, terminal=<tt>console.terminal</tt>] [,mode=<tt>TG_NONE</tt>])
<td>3.16
<td>external RLogin gateway (see <tt>TG_*</tt> in <tt>sbbsdefs.js</tt> for valid <i>mode</i> flags.)
<tr valign=top><td><b>check_syspass</b><td>boolean<td><tt>bbs.check_syspass([sys_pw])
<td>3.10
<td>verify system password, prompting for the password if not passed as an argument
<tr valign=top><td><b>good_password</b><td>boolean<td><tt>bbs.good_password(password)
<td>3.10
<td>check if requested user password meets minimum password requirements (length, uniqueness, etc.)
<tr valign=top><td><b>page_sysop</b><td>boolean<td><tt>bbs.page_sysop()
<td>3.10
<td>page the sysop for chat, returns <i>false</i> if the sysop could not be paged
<tr valign=top><td><b>page_guru</b><td>boolean<td><tt>bbs.page_guru()
<td>3.10
<td>page the guru for chat
<tr valign=top><td><b>multinode_chat</b><td>void<td><tt>bbs.multinode_chat()
<td>3.10
<td>enter multi-node chat
<tr valign=top><td><b>private_message</b><td>void<td><tt>bbs.private_message()
<td>3.10
<td>use the private inter-node message prompt
<tr valign=top><td><b>private_chat</b><td>void<td><tt>bbs.private_chat([local=<i>false</i>])
<td>3.10
<td>enter private inter-node chat, or local sysop chat (if <i>local</i>=<i>true</i>)
<tr valign=top><td><b>get_node_message</b><td>void<td><tt>bbs.get_node_message([clearline=<i>false</i>])
<td>3.10
<td>receive and display an inter-node message
<tr valign=top><td><b>put_node_message</b><td>boolean<td><tt>bbs.put_node_message([node_number] [,text])
<td>3.17
<td>send an inter-node message (specify a <i>node_number</i> value of <tt>-1</tt> for 'all active nodes')
<tr valign=top><td><b>get_telegram</b><td>void<td><tt>bbs.get_telegram([user_number=<i>current</i>], [clearline=<i>false</i>])
<td>3.10
<td>receive and display waiting telegrams for specified (or current) user
<tr valign=top><td><b>put_telegram</b><td>boolean<td><tt>bbs.put_telegram([user_number] [,text])
<td>3.17
<td>send a telegram (short multi-line stored message) to a user
<tr valign=top><td><b>list_nodes</b><td>void<td><tt>bbs.list_nodes()
<td>3.10
<td>list all nodes
<tr valign=top><td><b>whos_online</b><td>void<td><tt>bbs.whos_online()
<td>3.10
<td>list active nodes only (who's online)
<tr valign=top><td><b>spy</b><td>void<td><tt>bbs.spy(node_number)
<td>3.10
<td>spy on a node
<tr valign=top><td><b>cmdstr</b><td>string<td><tt>bbs.cmdstr(command_string [,fpath=<tt>""</tt>] [,fspec=<tt>""</tt>])
<td>3.10
<td>return expanded command string using Synchronet command-line specifiers
<tr valign=top><td><b>get_filespec</b><td>string<td><tt>bbs.get_filespec()
<td>3.10
<td>returns a file specification input by the user (optionally with wildcards)
<tr valign=top><td><b>get_newscantime</b><td>number<td><tt>bbs.get_newscantime(time=<i>current</i>)
<td>3.10
<td>confirm or change a new-scan time, returns the new new-scan time value (<i>time_t</i> format)
<tr valign=top><td><b>select_shell</b><td>boolean<td><tt>bbs.select_shell()
<td>3.10
<td>prompt user to select a new command shell
<tr valign=top><td><b>select_editor</b><td>boolean<td><tt>bbs.select_editor()
<td>3.10
<td>prompt user to select a new external message editor
<tr valign=top><td><b>get_time_left</b><td>number<td><tt>bbs.get_time_left()
<td>3.14b
<td>check the user's available remaining time online and return the value, in seconds<br>This method will inform (and disconnect) the user when they are out of time
<tr valign=top><td><b>compare_ars</b><td>boolean<td><tt>bbs.compare_ars(ars)
<td>3.15
<td>verify the current user online meets the specified Access Requirements String
<tr valign=top><td><b>select_node</b><td>number<td><tt>bbs.select_node(all_is_an_option=<i>false</i>)
<td>3.17
<td>Choose an active node to interact with.<br>Returns the selected node number, 0 (for none) or -1 for 'All'.
<tr valign=top><td><b>select_user</b><td>number<td><tt>bbs.select_user()
<td>3.17
<td>Choose a user to interact with.
</table>
<h2><a name=bbs.mods>bbs.mods object</a>
<br><font size=-1>Global repository for 3rd party modifications</font>
<font size=-1> - introduced in v3.12</font>
</h2>
<br>
<table border=1 width=100%>
<caption align=left><b><tt>bbs</tt>
<a name=bbs_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>sys_status</b><td>number
<td>3.10
<td>system status bitfield (see <tt>SS_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)
<tr valign=top><td><b>startup_options</b><td>number
<td>3.10
<td>startup options bitfield (see <tt>BBS_OPT_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)
<tr valign=top><td><b>answer_time</b><td>number
<td>3.10
<td>answer time, in <i>time_t</i> format
<tr valign=top><td><b>logon_time</b><td>number
<td>3.10
<td>logon time, in <i>time_t</i> format
<tr valign=top><td><b>start_time</b><td>number
<td>3.14
<td>time from which user's time left is calculated, in <i>time_t</i> format
<tr valign=top><td><b>new_file_time</b><td>number
<td>3.10
<td>current file new-scan time, in <i>time_t</i> format
<tr valign=top><td><b>last_new_file_time</b><td>number
<td>3.10
<td>previous file new-scan time, in <i>time_t</i> format
<tr valign=top><td><b>online</b><td>number
<td>3.10
<td>online (see <tt>ON_*</tt> in <tt>sbbsdefs.js</tt> for valid values)
<tr valign=top><td><b>time_left</b><td>number
<td>3.11
<td>time left (in seconds)
<tr valign=top><td><b>event_time</b><td>number
<td>3.11
<td>time of next exclusive event (in <i>time_t</i> format), or 0 if none
<tr valign=top><td><b>event_code</b><td>string
<td>3.11
<td>internal code of next exclusive event
<tr valign=top><td><b>node_num</b><td>number
<td>3.10
<td>current node number
<tr valign=top><td><b>node_settings</b><td>number
<td>3.10
<td>current node settings bitfield (see <tt>NM_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)
<tr valign=top><td><b>node_status</b><td>number
<td>3.17
<td>current node status value (see <tt>nodedefs.js</tt> for valid values)
<tr valign=top><td><b>node_errors</b><td>number
<td>3.17
<td>current node error counter
<tr valign=top><td><b>node_action</b><td>number
<td>3.10
<td>current node action (see <tt>nodedefs.js</tt> for valid values)
<tr valign=top><td><b>node_useron</b><td>number
<td>3.17
<td>current node user number (<i>useron</i> value)
<tr valign=top><td><b>node_connection</b><td>number
<td>3.17
<td>current node connection type (see <tt>nodedefs.js</tt> for valid values)
<tr valign=top><td><b>node_misc</b><td>number
<td>3.17
<td>current node misc value (see <tt>nodedefs.js</tt> for valid values)
<tr valign=top><td><b>node_aux</b><td>number
<td>3.17
<td>current node aux value
<tr valign=top><td><b>node_extaux</b><td>number
<td>3.17
<td>current node extended aux (<i>extaux</i>) value
<tr valign=top><td><b>node_val_user</b><td>number
<td>3.10
<td>validation feedback user for this node (or 0 for no validation feedback required)
<tr valign=top><td><b>logon_ulb</b><td>number
<td>3.10
<td>bytes uploaded during this session
<tr valign=top><td><b>logon_dlb</b><td>number
<td>3.10
<td>bytes downloaded during this session
<tr valign=top><td><b>logon_uls</b><td>number
<td>3.10
<td>files uploaded during this session
<tr valign=top><td><b>logon_dls</b><td>number
<td>3.10
<td>files downloaded during this session
<tr valign=top><td><b>logon_posts</b><td>number
<td>3.10
<td>messages posted during this session
<tr valign=top><td><b>logon_emails</b><td>number
<td>3.10
<td>e-mails sent during this session
<tr valign=top><td><b>logon_fbacks</b><td>number
<td>3.10
<td>feedback messages sent during this session
<tr valign=top><td><b>posts_read</b><td>number
<td>3.10
<td>messages read during this session
<tr valign=top><td><b>menu_dir</b><td>string
<td>3.10
<td>menu subdirectory (overrides default)
<tr valign=top><td><b>menu_file</b><td>string
<td>3.10
<td>menu file (overrides default)
<tr valign=top><td><b>main_cmds</b><td>number
<td>3.10
<td>total main menu commands received from user during this session
<tr valign=top><td><b>file_cmds</b><td>number
<td>3.10
<td>total file menu commands received from user during this session
<tr valign=top><td><b>curgrp</b><td>number
<td>3.10
<td>current message group
<tr valign=top><td><b>cursub</b><td>number
<td>3.10
<td>current message sub-board
<tr valign=top><td><b>cursub_code</b><td>string
<td>3.14
<td>current message sub-board internal code
<tr valign=top><td><b>curlib</b><td>number
<td>3.10
<td>current file library
<tr valign=top><td><b>curdir</b><td>number
<td>3.10
<td>current file directory
<tr valign=top><td><b>curdir_code</b><td>string
<td>3.14
<td>current file directory internal code
<tr valign=top><td><b>connection</b><td>string
<td>3.10
<td>remote connection type
<tr valign=top><td><b>rlogin_name</b><td>string
<td>3.10
<td>login name given during RLogin negotiation
<tr valign=top><td><b>rlogin_password</b><td>string
<td>3.15
<td>password specified during RLogin negotiation
<tr valign=top><td><b>rlogin_terminal</b><td>string
<td>3.16
<td>terminal specified during RLogin negotiation
<tr valign=top><td><b>client_name</b><td>string
<td>3.10
<td>client name
<tr valign=top><td><b>alt_ul_dir</b><td>number
<td>3.10
<td>current alternate upload path number
<tr valign=top><td><b>errorlevel</b><td>number
<td>3.12
<td>error level returned from last executed external program
<tr valign=top><td><b>smb_group</b><td>string
<td>3.10
<td>message group name of message being read
<tr valign=top><td><b>smb_group_desc</b><td>string
<td>3.10
<td>message group description of message being read
<tr valign=top><td><b>smb_group_number</b><td>number
<td>3.10
<td>message group number of message being read
<tr valign=top><td><b>smb_sub</b><td>string
<td>3.10
<td>sub-board name of message being read
<tr valign=top><td><b>smb_sub_desc</b><td>string
<td>3.10
<td>sub-board description of message being read
<tr valign=top><td><b>smb_sub_code</b><td>string
<td>3.10
<td>sub-board internal code of message being read
<tr valign=top><td><b>smb_sub_number</b><td>number
<td>3.10
<td>sub-board number of message being read
<tr valign=top><td><b>smb_attr</b><td>number
<td>3.10
<td>message base attributes
<tr valign=top><td><b>smb_last_msg</b><td>number
<td>3.10
<td>highest message number in message base
<tr valign=top><td><b>smb_total_msgs</b><td>number
<td>3.10
<td>total number of messages in message base
<tr valign=top><td><b>smb_msgs</b><td>number
<td>3.10
<td>number of messages loaded from message base
<tr valign=top><td><b>smb_curmsg</b><td>number
<td>3.10
<td>current message number in message base
<tr valign=top><td><b>msg_to</b><td>string
<td>3.10
<td>message recipient name
<tr valign=top><td><b>msg_to_ext</b><td>string
<td>3.10
<td>message recipient extension
<tr valign=top><td><b>msg_to_net</b><td>string
<td>3.10
<td>message recipient network address
<tr valign=top><td><b>msg_to_agent</b><td>number
<td>3.10
<td>message recipient agent type
<tr valign=top><td><b>msg_from</b><td>string
<td>3.10
<td>message sender name
<tr valign=top><td><b>msg_from_ext</b><td>string
<td>3.10
<td>message sender extension
<tr valign=top><td><b>msg_from_net</b><td>string
<td>3.10
<td>message sender network address
<tr valign=top><td><b>msg_from_agent</b><td>number
<td>3.10
<td>message sender agent type
<tr valign=top><td><b>msg_replyto</b><td>string
<td>3.10
<td>message reply-to name
<tr valign=top><td><b>msg_replyto_ext</b><td>string
<td>3.10
<td>message reply-to extension
<tr valign=top><td><b>msg_replyto_net</b><td>string
<td>3.10
<td>message reply-to network address
<tr valign=top><td><b>msg_replyto_agent</b><td>number
<td>3.10
<td>message reply-to agent type
<tr valign=top><td><b>msg_subject</b><td>string
<td>3.10
<td>message subject
<tr valign=top><td><b>msg_date</b><td>number
<td>3.10
<td>message date/time
<tr valign=top><td><b>msg_timezone</b><td>number
<td>3.10
<td>message time zone
<tr valign=top><td><b>msg_date_imported</b><td>number
<td>3.10
<td>message date/time imported
<tr valign=top><td><b>msg_attr</b><td>number
<td>3.10
<td>message attributes
<tr valign=top><td><b>msg_auxattr</b><td>number
<td>3.10
<td>message auxiliary attributes
<tr valign=top><td><b>msg_netattr</b><td>number
<td>3.10
<td>message network attributes
<tr valign=top><td><b>msg_offset</b><td>number
<td>3.10
<td>message header offset
<tr valign=top><td><b>msg_number</b><td>number
<td>3.10
<td>message number (unique, monotonically incrementing)
<tr valign=top><td><b>msg_expiration</b><td>number
<td>3.10
<td>message expiration
<tr valign=top><td><b>msg_forwarded</b><td>number
<td>3.10
<td>message forwarded
<tr valign=top><td><b>msg_thread_id</b><td>number
<td>3.16
<td>message thread identifier (0 if unknown)
<tr valign=top><td><b>msg_thread_back</b><td>number
<td>3.12
<td>message thread, back message number
<tr valign=top><td><b>msg_thread_next</b><td>number
<td>3.10
<td>message thread, next message number
<tr valign=top><td><b>msg_thread_first</b><td>number
<td>3.10
<td>message thread, message number of first reply to this message
<tr valign=top><td><b>msg_id</b><td>string
<td>3.10
<td>message identifier
<tr valign=top><td><b>msg_reply_id</b><td>string
<td>3.10
<td>message replied-to identifier
<tr valign=top><td><b>msg_delivery_attempts</b><td>number
<td>3.10
<td>message delivery attempt counter
<tr valign=top><td><b>msghdr_top_of_screen</b><td>number
<td>3.17c
<td>message header displayed at top-of-screen
<tr valign=top><td><b>file_name</b><td>string
<td>3.17
<td>file name
<tr valign=top><td><b>file_description</b><td>string
<td>3.17
<td>file description
<tr valign=top><td><b>file_dir_number</b><td>string
<td>3.17
<td>file directory (number)
<tr valign=top><td><b>file_attr</b><td>string
<td>3.17
<td>file attribute flags
<tr valign=top><td><b>file_date</b><td>string
<td>3.17
<td>file date
<tr valign=top><td><b>file_size</b><td>string
<td>3.17
<td>file size (in bytes)
<tr valign=top><td><b>file_credits</b><td>string
<td>3.17
<td>file credit value
<tr valign=top><td><b>file_uploader</b><td>string
<td>3.17
<td>file uploader (user name)
<tr valign=top><td><b>file_upload_date</b><td>string
<td>3.17
<td>file upload date
<tr valign=top><td><b>file_download_date</b><td>string
<td>3.17
<td>file last-download date
<tr valign=top><td><b>file_download_count</b><td>string
<td>3.17
<td>file download count
<tr valign=top><td><b>batch_upload_total</b><td>number
<td>3.10
<td>number of files in batch upload queue
<tr valign=top><td><b>batch_dnload_total</b><td>number
<td>3.10
<td>number of files in batch download queue
<tr valign=top><td><b>command_str</b><td>string
<td>3.14
<td>current command shell/module <i>command string</i> value
</table>
<h2><a name=console>console object</a>
<br><font size=-1>Controls the remote terminal</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>console</tt>
<a name=console_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>inkey</b><td>string<td><tt>console.inkey([mode=<tt>K_NONE</tt>] [,timeout=<tt>0</tt>])
<td>3.11
<td>get a single key with optional <i>timeout</i> in milliseconds (defaults to 0, for no wait).<br>Returns an empty string if there is no input (e.g. timeout occurs).<br>See <tt>K_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> flags.
<tr valign=top><td><b>getkey</b><td>string<td><tt>console.getkey([mode=<tt>K_NONE</tt>])
<td>3.10
<td>get a single key, with wait.<br>See <tt>K_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> flags.
<tr valign=top><td><b>getstr</b><td>string<td><tt>console.getstr([string] [,maxlen=<tt>128</tt>] [,mode=<tt>K_NONE</tt>] [,history[]])
<td>3.10
<td>get a text string from the user.<br>See <tt>K_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> flags.<br><i>history[]</i>, added in v3.17, allows a command history (string array) to be recalled using the up/down arrow keys.
<tr valign=top><td><b>getnum</b><td>number<td><tt>console.getnum([maxnum[, default]])
<td>3.10
<td>get a number between 1 and <i>maxnum</i> from the user with a default value of <i>default</i>
<tr valign=top><td><b>getkeys</b><td>number<td><tt>console.getkeys([keys] [,maxnum] [,mode=<tt>K_UPPER</tt>])
<td>3.10
<td>get one key from of a list of valid command <i>keys</i> (any key, if not specified), or a number between 1 and <i>maxnum</i>
<tr valign=top><td><b>gettemplate</b><td>string<td><tt>console.gettemplate(format [,string] [,mode=<tt>0</tt>])
<td>3.10
<td>get an input string based on specified template
<tr valign=top><td><b>ungetstr</b><td>void<td><tt>console.ungetstr(keys)
<td>3.10
<td>put one or more characters in the keyboard input buffer
<tr valign=top><td><b>yesno</b><td>boolean<td><tt>console.yesno(question [,mode = P_NONE])
<td>3.10
<td>YES/no question - returns <i>true</i> if 'yes' is selected
<tr valign=top><td><b>noyes</b><td>boolean<td><tt>console.noyes(question [,mode = P_NONE])
<td>3.10
<td>NO/yes question - returns <i>true</i> if 'no' is selected
<tr valign=top><td><b>mnemonics</b><td>void<td><tt>console.mnemonics(text)
<td>3.10
<td>print a mnemonics string, command keys highlighted with tilde (~) characters
<tr valign=top><td><b>clear</b><td>void<td><tt>console.clear([attribute] [,autopause=<tt>true</tt>])
<td>3.10
<td>clear screen and home cursor, optionally (in v3.13b+) setting current attribute first
<tr valign=top><td><b>home</b><td>void<td><tt>console.home()
<td>3.11
<td>send cursor to home position (x,y:1,1)
<tr valign=top><td><b>clearline</b><td>void<td><tt>console.clearline([attribute])
<td>3.10
<td>clear current line, optionally (in v3.13b+) setting current attribute first
<tr valign=top><td><b>cleartoeol</b><td>void<td><tt>console.cleartoeol([attribute])
<td>3.11
<td>clear to end-of-line, optionally (in v3.13b+) setting current attribute first
<tr valign=top><td><b>crlf</b><td>void<td><tt>console.crlf([count=<tt>1</tt>])
<td>3.10
<td>output <i>count</i> number of carriage-return/line-feed pairs (new-lines)
<tr valign=top><td><b>pause</b><td>void<td><tt>console.pause()
<td>3.10
<td>display pause prompt and wait for key hit
<tr valign=top><td><b>beep</b><td>void<td><tt>console.beep([count=<tt>1</tt>])
<td>3.11
<td>beep for <i>count</i> number of times (default count is 1)
<tr valign=top><td><b>print</b><td>void<td><tt>console.print([value [,value][...]] or [string [,mode=<tt>P_NONE</tt>]])
<td>3.10
<td>display one or more values as strings (supports Ctrl-A codes, Telnet-escaping, auto-screen pausing, etc.).<br>Supports a limited set of <tt>P_*</tt> flags, e.g. <tt>P_PETSCII</tt> and <tt>P_UTF8</tt>.
<tr valign=top><td><b>write</b><td>void<td><tt>console.write(value [,value])
<td>3.10
<td>display one or more values as raw strings (may include NULs)
<tr valign=top><td><b>writeln</b><td>void<td><tt>console.writeln(value [,value])
<td>3.15
<td>display one or more values as raw strings followed by a single carriage-return/line-feed pair (new-line)
<tr valign=top><td><b>putmsg</b><td>void<td><tt>console.putmsg(text [,mode=<tt>P_NONE</tt>] [,orig_columns=0] [,object scope])
<td>3.10
<td>display message text (Ctrl-A codes, @-codes, pipe codes, etc.).<br> See <tt>P_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> flags.<br>When <tt>P_WORDWRAP</tt> mode flag is specified, <i>orig_columns</i> specifies the original text column width, if known.<br>When <i>scope</i> is specified, <tt>@JS:property@</tt> codes will expand the referenced property names.
<tr valign=top><td><b>center</b><td>void<td><tt>console.center(text [,width])
<td>3.10
<td>display a string centered on the screen, with an optionally-specified screen width (in columns)
<tr valign=top><td><b>wide</b><td>void<td><tt>console.wide(text)
<td>3.17c
<td>display a string double-wide on the screen (sending "fullwidth" Unicode characters when possible)
<tr valign=top><td><b>strlen</b><td>number<td><tt>console.strlen(text [,mode=<tt>P_NONE</tt>])
<td>3.10
<td>returns the printed-length (number of columns) of the specified <i>text</i>, accounting for Ctrl-A codes
<tr valign=top><td><b>printfile</b><td>boolean<td><tt>console.printfile(filename [,mode=<tt>P_NONE</tt>] [,orig_columns=0] [,object scope])
<td>3.10
<td>print a message text file with optional mode.<br>When <tt>P_WORDWRAP</tt> mode flag is specified, <i>orig_columns</i> specifies the original text column width, if known.<br>When <i>scope</i> is specified, <tt>@JS:property@</tt> codes will expand the referenced property names.
<tr valign=top><td><b>printtail</b><td>boolean<td><tt>console.printtail(filename, lines [,mode=<tt>P_NONE</tt>] [,orig_columns=0] [,object scope])
<td>3.10
<td>print the last <i>n</i> lines of file with optional mode, original column width, and scope.
<tr valign=top><td><b>editfile</b><td>boolean<td><tt>console.editfile(filename)
<td>3.10
<td>edit/create a text file using the user's preferred message editor
<tr valign=top><td><b>uselect</b><td>number<td><tt>console.uselect([number, title, item] [,ars])
<td>3.12
<td>user selection menu, call for each item, then with no args to display select menu
<tr valign=top><td><b>saveline</b><td>boolean<td><tt>console.saveline()
<td>3.10
<td>push the current console line of text and attributes to a (local) LIFO list of //saved lines//
<tr valign=top><td><b>restoreline</b><td>boolean<td><tt>console.restoreline()
<td>3.10
<td>pop the most recently //saved line// of text and attributes and display it on the remote console
<tr valign=top><td><b>ansi</b><td>string<td><tt>console.ansi(attribute [,current_attribute])
<td>3.10
<td>returns ANSI sequence required to generate specified terminal <i>attribute</i> (e.g. <tt>YELLOW|HIGH|BG_BLUE</tt>), if <i>current_attribute</i> is specified, an optimized ANSI sequence may be returned
<tr valign=top><td><b>pushxy</b><td>void<td><tt>console.pushxy()
<td>3.11
<td>save the current cursor position (x and y coordinates) in the remote terminal
<tr valign=top><td><b>popxy</b><td>void<td><tt>console.popxy()
<td>3.11
<td>restore a saved cursor position to the remote terminal (requires terminal support, e.g. ANSI)
<tr valign=top><td><b>gotoxy</b><td>void<td><tt>console.gotoxy([x,y] or [object { x,y }])
<td>3.11
<td>move cursor to a specific screen coordinate (ANSI or PETSCII, 1-based values), arguments can be separate x and y coordinates or an object with x and y properties (like that returned from <tt>console.getxy()</tt>)
<tr valign=top><td><b>up</b><td>void<td><tt>console.up([rows=<tt>1</tt>])
<td>3.11
<td>move cursor up one or more rows
<tr valign=top><td><b>down</b><td>void<td><tt>console.down([rows=<tt>1</tt>])
<td>3.11
<td>move cursor down one or more rows
<tr valign=top><td><b>right</b><td>void<td><tt>console.right([columns=<tt>1</tt>])
<td>3.11
<td>move cursor right one or more columns
<tr valign=top><td><b>left</b><td>void<td><tt>console.left([columns=<tt>1</tt>])
<td>3.11
<td>move cursor left one or more columns
<tr valign=top><td><b>getdimensions</b><td>void<td><tt>console.getdimensions()
<td>3.11
<td>query the number of rows and columns on the remote terminal
<tr valign=top><td><b>getxy</b><td>object<td><tt>console.getxy()
<td>3.11
<td>query the current cursor position on the remote (ANSI) terminal and returns the coordinates as an object (with <tt>x</tt> and <tt>y</tt> properties) or <tt>false</tt> on failure
<tr valign=top><td><b>lock_input</b><td>void<td><tt>console.lock_input([lock=<tt>true</tt>])
<td>3.10
<td>lock the user input thread (allowing direct client socket access)
<tr valign=top><td><b>telnet_cmd</b><td>boolean<td><tt>console.telnet_cmd(command [,option=<tt>0</tt>] [,timeout=<tt>0</tt>])
<td>3.17
<td>send Telnet command (with optional command option) to remote client, if the optional timeout is specified (in milliseconds, added in v3.17), then an acknowledgment will be expected and the return value will indicate whether or not one was received
<tr valign=top><td><b>handle_ctrlkey</b><td>boolean<td><tt>console.handle_ctrlkey(key [,mode=<tt>K_NONE</tt>])
<td>3.11
<td>call internal control key handler for specified control key, returns <tt>true</tt> if handled
<tr valign=top><td><b>term_supports</b><td>boolean<td><tt>console.term_supports([terminal_flags])
<td>3.14
<td>either returns <i>bool</i>, indicating whether or not the current user/client supports all the specified <i>terminal_flags</i>, or returns the current user/client's <i>terminal_flags</i> (numeric bit-field) if no <i>terminal_flags</i> were specified
<tr valign=top><td><b>backspace</b><td>void<td><tt>console.backspace([count=<tt>1</tt>])
<td>3.15
<td>send a destructive backspace sequence
<tr valign=top><td><b>creturn</b><td>void<td><tt>console.creturn([count=<tt>1</tt>])
<td>3.17
<td>send a carriage return sequence
<tr valign=top><td><b>clearkeybuffer</b><td>void<td><tt>console.clearkeybuffer()
<td>3.15
<td>clear keyboard input buffer
<tr valign=top><td><b>getbyte</b><td>number<td><tt>console.getbyte([timeout=<tt>0</tt>])
<td>3.17
<td>returns an unprocessed input byte from the remote terminal with optional <i>timeout</i> in milliseconds (defaults to 0, for no wait), returns <i>null</i> on failure (timeout)
<tr valign=top><td><b>putbyte</b><td>boolean<td><tt>console.putbyte(value)
<td>3.17
<td>sends an unprocessed byte value to the remote terminal
<tr valign=top><td><b>add_hotspot</b><td>void<td><tt>console.add_hotspot(cmd [,bool hungry=<tt>true</tt>] [,min_x] [,max_x] [,y])
<td>3.18
<td>adds a mouse hot-spot (a clickable screen area that generates keyboard input)
<tr valign=top><td><b>clear_hotspots</b><td>void<td><tt>console.clear_hotspots()
<td>3.18
<td>clear all current mouse hot-spots
<tr valign=top><td><b>scroll_hotspots</b><td>void<td><tt>console.scroll_hotspots([rows=1])
<td>3.18
<td>scroll all current mouse hot-spots by the specific number of rows
</table>
<br>
<table border=1 width=100%>
<caption align=left><b><tt>console</tt>
<a name=console_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>status</b><td>number
<td>3.10
<td>status bit-field (see <tt>CON_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)
<tr valign=top><td><b>mouse_mode</b><td>number
<td>3.18
<td>mouse mode bit-field (see <tt>MOUSE_MODE_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)
<tr valign=top><td><b>line_counter</b><td>number
<td>3.10
<td>current 0-based line counter (used for automatic screen pause)
<tr valign=top><td><b>current_row</b><td>number
<td>3.18
<td>current 0-based row counter
<tr valign=top><td><b>current_column</b><td>number
<td>3.15
<td>current 0-based column counter (used to auto-increment <i>line_counter</i> when screen wraps)
<tr valign=top><td><b>last_line_length</b><td>number
<td>3.17
<td>length of last line sent to terminal (before a carriage-return or line-wrap)
<tr valign=top><td><b>attributes</b><td>number
<td>3.10
<td>current display attributes (set with number or string value)
<tr valign=top><td><b>top_of_screen</b><td>number
<td>3.10
<td>set to <i>true</i> if the terminal cursor is already at the top of the screen - <small>READ ONLY</small>
<tr valign=top><td><b>screen_rows</b><td>number
<td>3.10
<td>number of remote terminal screen rows (in lines)
<tr valign=top><td><b>screen_columns</b><td>number
<td>3.11
<td>number of remote terminal screen columns (in character cells)
<tr valign=top><td><b>tabstop</b><td>number
<td>3.17
<td>current tab stop interval (tab size), in columns
<tr valign=top><td><b>autoterm</b><td>number
<td>3.10
<td>bit-field of automatically detected terminal settings (see <tt>USER_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)
<tr valign=top><td><b>terminal</b><td>string
<td>3.11
<td>terminal type description, possibly supplied by client (e.g. 'ANSI')
<tr valign=top><td><b>type</b><td>string
<td>3.17c
<td>terminal type (i.e. 'ANSI', 'RIP', 'PETSCII', or 'DUMB')
<tr valign=top><td><b>charset</b><td>string
<td>3.17c
<td>terminal character set (i.e. 'UTF-8', 'CP437', 'CBM-ASCII', or 'US-ASCII')
<tr valign=top><td><b>cterm_version</b><td>number
<td>3.17
<td>detected CTerm (SyncTERM) version as an integer > 1000 where major version is cterm_version / 1000 and minor version is cterm_version % 1000
<tr valign=top><td><b>inactivity_warning</b><td>number
<td>3.14b
<td>number of seconds before displaying warning (Are you really there?) due to user/keyboard inactivity
<tr valign=top><td><b>inactivity_hangup</b><td>number
<td>3.14b
<td>number of seconds before disconnection due to user/keyboard inactivity
<tr valign=top><td><b>timeout</b><td>number
<td>3.10
<td>user/keyboard inactivity timeout reference value (time_t format)
<tr valign=top><td><b>timeleft_warning</b><td>number
<td>3.10
<td>number of low time-left (5 or fewer minutes remaining) warnings displayed to user
<tr valign=top><td><b>aborted</b><td>boolean
<td>3.10
<td>input/output has been aborted
<tr valign=top><td><b>abortable</b><td>boolean
<td>3.10
<td>remote output can be asynchronously aborted with Ctrl-C
<tr valign=top><td><b>telnet_mode</b><td>number
<td>3.10
<td>current Telnet mode bit-field (see <tt>TELNET_MODE_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)
<tr valign=top><td><b>wordwrap</b><td>string
<td>3.10
<td>word-wrap buffer (used by getstr) - <small>READ ONLY</small>
<tr valign=top><td><b>question</b><td>string
<td>3.10
<td>current yes/no question (set by yesno and noyes)
<tr valign=top><td><b>getstr_offset</b><td>number
<td>3.11
<td>cursor position offset for use with <tt>getstr(K_USEOFFSET)</tt>
<tr valign=top><td><b>ctrlkey_passthru</b><td>number
<td>3.10
<td>control key pass-through bit-mask, set bits represent control key combinations <i>not</i> handled by <tt>inkey()</tt> method This may optionally be specified as a string of characters. The format of this string is [+-][@-_]. If neither plus nor minus is the first character, the value will be replaced by one constructed from the string. A + indicates that characters following will be added to the set, and a - indicates they should be removed. ex: <tt>console.ctrlkey_passthru="-UP+AB"</tt> will clear CTRL-U and CTRL-P and set CTRL-A and CTRL-B.
<tr valign=top><td><b>input_buffer_level</b><td>number
<td>3.12
<td>number of bytes currently in the input buffer (from the remote client) - <small>READ ONLY</small>
<tr valign=top><td><b>input_buffer_space</b><td>number
<td>3.12
<td>number of bytes available in the input buffer	- <small>READ ONLY</small>
<tr valign=top><td><b>output_buffer_level</b><td>number
<td>3.12
<td>number of bytes currently in the output buffer (from the local server) - <small>READ ONLY</small>
<tr valign=top><td><b>output_buffer_space</b><td>number
<td>3.12
<td>number of bytes available in the output buffer - <small>READ ONLY</small>
<tr valign=top><td><b>output_rate</b><td>number
<td>3.17c
<td>emulated serial data output rate, in bits-per-second (0 = unlimited)
<tr valign=top><td><b>keyboard_buffer_level</b><td>number
<td>3.18
<td>number of characters current in the keyboard input buffer (from <tt>ungetstr</tt>) - <small>READ ONLY</small>
<tr valign=top><td><b>keyboard_buffer_space</b><td>number
<td>3.18
<td>number of characters spaces available in the keyboard input buffer - <small>READ ONLY</small>
</table>
<h2><a name=msg_area>msg_area object</a>
<br><font size=-1>Message Areas</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>msg_area</tt>
<a name=msg_area_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>settings</b><td>number
<td>message area settings (bitfield) - see <tt>MM_*</tt> in <tt>sbbsdefs.js</tt> for details
<tr valign=top><td><b>fido_netmail_settings</b><td>number
<td>FidoNet NetMail settings (bitfield) - see <tt>NMAIL_*</tt> in <tt>sbbsdefs.js</tt> for details
<tr valign=top><td><b>inet_netmail_settings</b><td>number
<td>Internet NetMail settings (bitfield) - see <tt>NMAIL_*</tt> in <tt>sbbsdefs.js</tt> for details
</table>
<h2><a name=msg_area.grp>msg_area.grp object</a>
<br><font size=-1>Associative array of all groups (use name as index)</font>
<font size=-1> - introduced in v3.12</font>
</h2>
<h2><a name=msg_area.sub>msg_area.sub object</a>
<br><font size=-1>Associative array of all sub-boards (use internal code as index)</font>
<font size=-1> - introduced in v3.11</font>
</h2>
<h2><a name=msg_area.grp_list>msg_area.grp_list array</a>
<br><font size=-1>Message Groups (current user has access to)</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>msg_area.grp_list</tt>
<a name=msg_area.grp_list_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>index</b><td>number
<td>index into grp_list array (or -1 if not in array) <i>(introduced in v3.12)</i>
<tr valign=top><td><b>number</b><td>number
<td>unique number for this message group
<tr valign=top><td><b>name</b><td>string
<td>group name
<tr valign=top><td><b>description</b><td>string
<td>group description
<tr valign=top><td><b>ars</b><td>string
<td>group access requirements
<tr valign=top><td><b>can_access</b><td>boolean
<td>user has sufficient access to list this group's sub-boards <i>(introduced in v3.18)</i>
</table>
<h2><a name=msg_area.grp_list.sub_list>msg_area.grp_list.sub_list array</a>
<br><font size=-1>Message Sub-boards (current user has access to)</h2>(all properties are <small>READ ONLY</small> except for <i>scan_ptr</i>, <i>scan_cfg</i>, and <i>last_read</i>)</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>msg_area.grp_list.sub_list</tt>
<a name=msg_area.grp_list.sub_list_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>index</b><td>number
<td>index into sub_list array (or -1 if not in array) <i>(introduced in v3.12)</i>
<tr valign=top><td><b>grp_index</b><td>number
<td>group's index into grp_list array <i>(introduced in v3.12)</i>
<tr valign=top><td><b>number</b><td>number
<td>unique number for this sub-board
<tr valign=top><td><b>grp_number</b><td>number
<td>group number
<tr valign=top><td><b>grp_name</b><td>string
<td>group name <i>(introduced in v3.12)</i>
<tr valign=top><td><b>code</b><td>string
<td>sub-board internal code
<tr valign=top><td><b>name</b><td>string
<td>sub-board name
<tr valign=top><td><b>description</b><td>string
<td>sub-board description
<tr valign=top><td><b>qwk_name</b><td>string
<td>sub-board QWK name
<tr valign=top><td><b>newsgroup</b><td>string
<td>newsgroup name (as configured or dymamically generated)
<tr valign=top><td><b>ars</b><td>string
<td>sub-board access requirements
<tr valign=top><td><b>read_ars</b><td>string
<td>sub-board reading requirements
<tr valign=top><td><b>post_ars</b><td>string
<td>sub-board posting requirements
<tr valign=top><td><b>operator_ars</b><td>string
<td>sub-board operator requirements
<tr valign=top><td><b>moderated_ars</b><td>string
<td>sub-board moderated-user requirements (if non-blank)
<tr valign=top><td><b>data_dir</b><td>string
<td>sub-board data storage location
<tr valign=top><td><b>fidonet_origin</b><td>string
<td>FidoNet origin line
<tr valign=top><td><b>qwknet_tagline</b><td>string
<td>QWK Network tagline
<tr valign=top><td><b>settings</b><td>number
<td>toggle options (bitfield) - see <tt>SUB_*</tt> in <tt>sbbsdefs.js</tt> for details
<tr valign=top><td><b>ptridx</b><td>number
<td>index into message scan configuration/pointer file
<tr valign=top><td><b>qwk_conf</b><td>number
<td>QWK conference number
<tr valign=top><td><b>max_crcs</b><td>number
<td>configured maximum number of message CRCs to store (for dupe checking)
<tr valign=top><td><b>max_msgs</b><td>number
<td>configured maximum number of messages before purging
<tr valign=top><td><b>max_age</b><td>number
<td>configured maximum age (in days) of messages before expiration
<tr valign=top><td><b>print_mode</b><td>number
<td>additional print mode flags to use when printing messages - see <tt>P_*</tt> in <tt>sbbsdefs.js</tt> for details
<tr valign=top><td><b>print_mode_neg</b><td>number
<td>print mode flags to <i>negate</i> when printing messages - see <tt>P_*</tt> in <tt>sbbsdefs.js</tt> for details
<tr valign=top><td><b>can_access</b><td>boolean
<td>user has sufficient access to see this sub-board
<tr valign=top><td><b>can_read</b><td>boolean
<td>user has sufficient access to read messages in this sub-board
<tr valign=top><td><b>can_post</b><td>boolean
<td>user has sufficient access to post messages in this sub-board
<tr valign=top><td><b>is_operator</b><td>boolean
<td>user has operator access to this sub-board
<tr valign=top><td><b>is_moderated</b><td>boolean
<td>user's posts are moderated
<tr valign=top><td><b>scan_ptr</b><td>undefined
<td>user's current new message scan pointer (highest-read message number)
<tr valign=top><td><b>scan_cfg</b><td>undefined
<td>user's message scan configuration (bitfield) - see <tt>SCAN_CFG_*</tt> in <tt>sbbsdefs.js</tt> for details
<tr valign=top><td><b>last_read</b><td>undefined
<td>user's last-read message number
</table>
<h2><a name=file_area>file_area object</a>
<br><font size=-1>File Transfer Areas</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>file_area</tt>
<a name=file_area_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>min_diskspace</b><td>number
<td>minimum amount of available disk space (in kilobytes) required for user uploads to be allowed
<tr valign=top><td><b>settings</b><td>number
<td>file area settings (bitfield) - see <tt>FM_*</tt> in <tt>sbbsdefs.js</tt> for details
<tr valign=top><td><b>alt_paths</b><td>object
<td>array of alternative file paths.  NOTE: this array is zero-based, but alt path fields are one-based.
</table>
<h2><a name=file_area.lib>file_area.lib object</a>
<br><font size=-1>Associative array of all libraries (use name as index)</font>
<font size=-1> - introduced in v3.12</font>
</h2>
<h2><a name=file_area.dir>file_area.dir object</a>
<br><font size=-1>Associative array of all directories (use internal code as index)</font>
<font size=-1> - introduced in v3.11</font>
</h2>
<h2><a name=file_area.lib_list>file_area.lib_list array</a>
<br><font size=-1>File Transfer Libraries (current user has access to)</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>file_area.lib_list</tt>
<a name=file_area.lib_list_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>index</b><td>number
<td>index into lib_list array (or -1 if not in array) <i>(introduced in v3.12)</i>
<tr valign=top><td><b>number</b><td>number
<td>unique number for this library
<tr valign=top><td><b>name</b><td>string
<td>library name
<tr valign=top><td><b>description</b><td>string
<td>library description
<tr valign=top><td><b>ars</b><td>string
<td>library access requirements
<tr valign=top><td><b>link</b><td>string
<td>library link (for HTML index)
<tr valign=top><td><b>can_access</b><td>boolean
<td>user has sufficient access to this library's directories <i>(introduced in v3.18)</i>
</table>
<h2><a name=file_area.lib_list.dir_list>file_area.lib_list.dir_list array</a>
<br><font size=-1>File Transfer Directories  (current user has access to)</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>file_area.lib_list.dir_list</tt>
<a name=file_area.lib_list.dir_list_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>index</b><td>number
<td>index into dir_list array (or -1 if not in array) <i>(introduced in v3.12)</i>
<tr valign=top><td><b>number</b><td>number
<td>unique number for this directory
<tr valign=top><td><b>lib_index</b><td>number
<td>library index <i>(introduced in v3.12)</i>
<tr valign=top><td><b>lib_number</b><td>number
<td>library number
<tr valign=top><td><b>lib_name</b><td>string
<td>library name <i>(introduced in v3.12)</i>
<tr valign=top><td><b>code</b><td>string
<td>directory internal code
<tr valign=top><td><b>name</b><td>string
<td>directory name
<tr valign=top><td><b>description</b><td>string
<td>directory description
<tr valign=top><td><b>path</b><td>string
<td>directory file storage location
<tr valign=top><td><b>ars</b><td>string
<td>directory access requirements
<tr valign=top><td><b>upload_ars</b><td>string
<td>directory upload requirements
<tr valign=top><td><b>download_ars</b><td>string
<td>directory download requirements
<tr valign=top><td><b>exempt_ars</b><td>string
<td>directory exemption requirements
<tr valign=top><td><b>operator_ars</b><td>string
<td>directory operator requirements
<tr valign=top><td><b>extensions</b><td>string
<td>allowed file extensions (comma delimited)
<tr valign=top><td><b>upload_sem</b><td>string
<td>upload semaphore file
<tr valign=top><td><b>data_dir</b><td>string
<td>directory data storage location
<tr valign=top><td><b>settings</b><td>number
<td>toggle options (bitfield)
<tr valign=top><td><b>seqdev</b><td>number
<td>sequential (slow storage) device number
<tr valign=top><td><b>sort</b><td>number
<td>sort order (see <tt>SORT_*</tt> in <tt>sbbsdefs.js</tt> for valid values)
<tr valign=top><td><b>max_files</b><td>number
<td>configured maximum number of files
<tr valign=top><td><b>max_age</b><td>number
<td>configured maximum age (in days) of files before expiration
<tr valign=top><td><b>upload_credit_pct</b><td>number
<td>percent of file size awarded uploader in credits upon file upload
<tr valign=top><td><b>download_credit_pct</b><td>number
<td>percent of file size awarded uploader in credits upon subsequent downloads
<tr valign=top><td><b>link</b><td>string
<td>directory link (for HTML index)
<tr valign=top><td><b>can_access</b><td>boolean
<td>user has sufficient access to view this directory (e.g. list files) <i>(introduced in v3.18)</i>
<tr valign=top><td><b>can_upload</b><td>boolean
<td>user has sufficient access to upload files to this directory
<tr valign=top><td><b>can_download</b><td>boolean
<td>user has sufficient access to download files from this directory
<tr valign=top><td><b>is_exempt</b><td>boolean
<td>user is exempt from download credit costs (or the directory is configured for free downloads)
<tr valign=top><td><b>is_operator</b><td>boolean
<td>user has operator access to this directory
<tr valign=top><td><b>is_offline</b><td>boolean
<td>directory is for offline storage <i>(introduced in v3.14)</i>
<tr valign=top><td><b>is_upload</b><td>boolean
<td>directory is for uploads only <i>(introduced in v3.14)</i>
<tr valign=top><td><b>is_sysop</b><td>boolean
<td>directory is for uploads to sysop only <i>(introduced in v3.14)</i>
</table>
<h2><a name=xtrn_area>xtrn_area object</a>
<br><font size=-1>External Program Areas</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<h2><a name=xtrn_area.sec>xtrn_area.sec object</a>
<br><font size=-1>Associative array of all external program sections (use internal code as index)</font>
<font size=-1> - introduced in v3.12</font>
</h2>
<h2><a name=xtrn_area.prog>xtrn_area.prog object</a>
<br><font size=-1>Associative array of all external programs (use internal code as index)</font>
<font size=-1> - introduced in v3.11</font>
</h2>
<h2><a name=xtrn_area.sec_list>xtrn_area.sec_list array</a>
<br><font size=-1>Online Program (door) Sections (current user has access to)</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>xtrn_area.sec_list</tt>
<a name=xtrn_area.sec_list_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>index</b><td>number
<td>index into sec_list array (or -1 if not in index) <i>(introduced in v3.12)</i>
<tr valign=top><td><b>number</b><td>number
<td>unique number for this external program section
<tr valign=top><td><b>code</b><td>string
<td>external program section internal code
<tr valign=top><td><b>name</b><td>string
<td>external program section name
<tr valign=top><td><b>ars</b><td>string
<td>external program section access requirements
<tr valign=top><td><b>can_access</b><td>boolean
<td>user has sufficient access to enter this section <i>(introduced in v3.15)</i>
</table>
<h2><a name=xtrn_area.sec_list.prog_list>xtrn_area.sec_list.prog_list array</a>
<br><font size=-1>Online External Programs (doors) (current user has access to)</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>xtrn_area.sec_list.prog_list</tt>
<a name=xtrn_area.sec_list.prog_list_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>index</b><td>number
<td>index into prog_list array (or -1 if not in index) <i>(introduced in v3.12)</i>
<tr valign=top><td><b>number</b><td>number
<td>program number
<tr valign=top><td><b>sec_index</b><td>number
<td>program section index <i>(introduced in v3.12)</i>
<tr valign=top><td><b>sec_number</b><td>number
<td>program section number
<tr valign=top><td><b>sec_code</b><td>string
<td>program section internal code <i>(introduced in v3.12)</i>
<tr valign=top><td><b>code</b><td>string
<td>internal code
<tr valign=top><td><b>name</b><td>string
<td>name
<tr valign=top><td><b>cmd</b><td>string
<td>command-line
<tr valign=top><td><b>clean_cmd</b><td>string
<td>clean-up command-line
<tr valign=top><td><b>startup_dir</b><td>string
<td>startup directory
<tr valign=top><td><b>ars</b><td>string
<td>access requirements
<tr valign=top><td><b>execution_ars</b><td>string
<td>execution requirements
<tr valign=top><td><b>settings</b><td>number
<td>toggle options (bitfield)
<tr valign=top><td><b>type</b><td>number
<td>drop file type
<tr valign=top><td><b>event</b><td>number
<td>event type (0=none)
<tr valign=top><td><b>textra</b><td>number
<td>extra time given to users running this program
<tr valign=top><td><b>max_time</b><td>number
<td>maximum time allowed in program
<tr valign=top><td><b>cost</b><td>number
<td>execution cost (credits to run this program)
<tr valign=top><td><b>can_access</b><td>boolean
<td>user has sufficient access to see this program
<tr valign=top><td><b>can_run</b><td>boolean
<td>user has sufficient access to run this program
</table>
<h2><a name=xtrn_area.event>xtrn_area.event object</a>
<br><font size=-1>Associative array of all timed events (use internal code as index)</font>
<font size=-1> - introduced in v3.11</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>xtrn_area.event</tt>
<a name=xtrn_area.event_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>cmd</b><td>string
<td>command-line
<tr valign=top><td><b>startup_dir</b><td>string
<td>startup directory
<tr valign=top><td><b>node_num</b><td>number
<td>node number
<tr valign=top><td><b>time</b><td>number
<td>time to execute
<tr valign=top><td><b>freq</b><td>number
<td>frequency to execute
<tr valign=top><td><b>days</b><td>number
<td>days of week to execute (bitfield)
<tr valign=top><td><b>mdays</b><td>number
<td>days of month to execute (bitfield)
<tr valign=top><td><b>months</b><td>number
<td>months of year to execute (bitfield)
<tr valign=top><td><b>last_run</b><td>number
<td>date/time last run (in time_t format)
<tr valign=top><td><b>settings</b><td>number
<td>toggle options (bitfield)
</table>
<h2><a name=xtrn_area.editor>xtrn_area.editor object</a>
<br><font size=-1>Associative array of all external editors (use internal code as index)</font>
<font size=-1> - introduced in v3.11</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>xtrn_area.editor</tt>
<a name=xtrn_area.editor_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>name</b><td>string
<td>name
<tr valign=top><td><b>cmd</b><td>string
<td>command-line
<tr valign=top><td><b>ars</b><td>string
<td>access requirements
<tr valign=top><td><b>settings</b><td>number
<td>toggle options (bitfield)
<tr valign=top><td><b>type</b><td>number
<td>drop file type
</table>
<h2><a name=MsgBase>MsgBase class</a>
<br><font size=-1>Class used for accessing message bases</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<p>To create a new MsgBase object: <tt>var msgbase = new MsgBase('<i>code</i>')</tt><br>where <i>code</i> is a sub-board internal code, or <tt>mail</tt> for the e-mail message base.<p>The MsgBase retrieval methods that accept a <tt>by_offset</tt> argument as their optional first boolean argument will interpret the following <i>number</i> argument as either a 1-based unique message number (by_offset=<tt>false</tt>) or a 0-based message index-offset (by_offset=<tt>true</tt>). Retrieving messages by offset is faster than by number or message-id (string). Passing an existing message <i>header object</i> to the retrieval methods that support it (e.g. <tt>get_msg_body()</tt>) is even faster. </p>
<table border=1 width=100%>
<caption align=left><b><tt>MsgBase</tt>
<a name=MsgBase_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>open</b><td>boolean<td><tt>MsgBase.open()
<td>3.10
<td>open message base
<tr valign=top><td><b>close</b><td>boolean<td><tt>MsgBase.close()
<td>3.10
<td>close message base (if open)
<tr valign=top><td><b>get_msg_header</b><td>object<td><tt>MsgBase.get_msg_header([by_offset=<tt>false</tt>,] number_or_offset_or_id [,expand_fields=<tt>true</tt>] [,include_votes=<tt>false</tt>])
<td>3.12
<td>returns a specific message header, <i>null</i> on failure. <br><i>New in v3.12:</i> Pass <i>false</i> for the <i>expand_fields</i> argument (default: <i>true</i>) if you will be re-writing the header later with <i>put_msg_header()</i><br>Additional read-only header properties: <i>mime_version</i>, <i>content_type</i>, and <i>is_utf8</i>
<tr valign=top><td><b>get_all_msg_headers</b><td>object<td><tt>MsgBase.get_all_msg_headers([include_votes=<tt>false</tt>] [,expand_fields=<tt>true</tt>])
<td>3.16
<td>returns an object (associative array) of all message headers "indexed" by message number.<br>Message headers returned by this function include additional properties: <tt>upvotes</tt>, <tt>downvotes</tt> and <tt>total_votes</tt>.<br>Vote messages are excluded by default.
<tr valign=top><td><b>put_msg_header</b><td>boolean<td><tt>MsgBase.put_msg_header([by_offset=<tt>false</tt>,] [number_or_offset_or_id,] object header)
<td>3.10
<td>modify an existing message header (must have been 'got' without expanded fields)
<tr valign=top><td><b>get_msg_body</b><td>string<td><tt>MsgBase.get_msg_body([by_offset=<tt>false</tt>,] number_or_offset_or_id_or_header [,strip_ctrl_a=<tt>false</tt>] [,dot_stuffing=<tt>false</tt>] [,include_tails=<tt>true</tt>] [,plain_text=<tt>false</tt>])
<td>3.10
<td>returns the entire body text of a specific message as a single String, <i>null</i> on failure. The default behavior is to leave Ctrl-A codes intact, do not stuff dots (e.g. per RFC-821), and to include tails (if any) in the returned body text. When <i>plain_text</i> is true, only the first plain-text portion of a multi-part MIME encoded message body is returned. The first argument (following the optional <i>by_offset</i> boolean) must be either a number (message number or index-offset), string (message-ID), or object (message header). The <i>by_offfset</i> (<tt>true</tt>) argument should only be passed when the argument following it is the numeric index-offset of the message to be retrieved. By default (<i>by_offset</i>=<tt>false</tt>), a numeric argument would be interpreted as the message <i>number</i> to be retrieved.<br>After reading a multi-part MIME-encoded message, new header properties may be available: <i>text_charset</i> and <i>text_subtype</i>.
<tr valign=top><td><b>get_msg_tail</b><td>string<td><tt>MsgBase.get_msg_tail([by_offset=<tt>false</tt>,] number_or_offset_or_id_or_header [,strip_ctrl_a]=<tt>false</tt>)
<td>3.10
<td>returns the tail text of a specific message, <i>null</i> on failure
<tr valign=top><td><b>get_msg_index</b><td>object<td><tt>MsgBase.get_msg_index([by_offset=<tt>false</tt>,] number_or_offset, [include_votes=<tt>false</tt>])
<td>3.11
<td>returns a specific message index record, <i>null</i> on failure. The index object will contain the following properties:<br><table><tr><td align=top><tt>attr</tt><td>Attribute bitfield<tr><td align=top><tt>time</tt><td>Date/time imported (in time_t format)<tr><td align=top><tt>number</tt><td>Message number<tr><td align=top><tt>offset</tt><td>Record number in index file</table>Indexes of regular messages will contain the following additional properties:<br><table><tr><td align=top><tt>subject</tt><td>CRC-16 of lowercase message subject<tr><td align=top><tt>to</tt><td>CRC-16 of lowercase recipient's name (or user number if e-mail)<tr><td align=top><tt>from</tt><td>CRC-16 of lowercase sender's name (or user number if e-mail)</table>Indexes of vote messages will contain the following additional properties:<br><table><tr><td align=top><tt>vote</tt><td>vote value<tr><td align=top><tt>remsg</tt><td>number of message this vote is in response to</table>
<tr valign=top><td><b>get_index</b><td>array<td><tt>MsgBase.get_index()
<td>3.17c
<td>return an array of message index records represented as objects, the same format as returned by <i>get_msg_index()</i><br>This is the fastest method of obtaining a list of all message index records.
<tr valign=top><td><b>remove_msg</b><td>boolean<td><tt>MsgBase.remove_msg([by_offset=<tt>false</tt>,] number_or_offset_or_id)
<td>3.11
<td>mark message for deletion
<tr valign=top><td><b>save_msg</b><td>boolean<td><tt>MsgBase.save_msg(object header [,client=<i>none</i>] [,body_text=<tt>""</tt>] [,array rcpt_list=<i>none</i>])
<td>3.12
<td>create a new message in message base, the <i>header</i> object may contain the following properties:<br><table><tr><td align=top><tt>subject</tt><td>Message subject <i>(required)</i><tr><td align=top><tt>to</tt><td>Recipient's name <i>(required)</i><tr><td align=top><tt>to_ext</tt><td>Recipient's user number (for local e-mail)<tr><td align=top><tt>to_org</tt><td>Recipient's organization<tr><td align=top><tt>to_net_type</tt><td>Recipient's network type (default: 0 for local)<tr><td align=top><tt>to_net_addr</tt><td>Recipient's network address<tr><td align=top><tt>to_agent</tt><td>Recipient's agent type<tr><td align=top><tt>to_list</tt><td>Comma-separated listed of primary recipients, RFC822-style<tr><td align=top><tt>cc_list</tt><td>Comma-separated listed of secondary recipients, RFC822-style<tr><td align=top><tt>from</tt><td>Sender's name <i>(required)</i><tr><td align=top><tt>from_ext</tt><td>Sender's user number<tr><td align=top><tt>from_org</tt><td>Sender's organization<tr><td align=top><tt>from_net_type</tt><td>Sender's network type (default: 0 for local)<tr><td align=top><tt>from_net_addr</tt><td>Sender's network address<tr><td align=top><tt>from_agent</tt><td>Sender's agent type<tr><td align=top><tt>from_ip_addr</tt><td>Sender's IP address (if available, for security tracking)<tr><td align=top><tt>from_host_name</tt><td>Sender's host name (if available, for security tracking)<tr><td align=top><tt>from_protocol</tt><td>TCP/IP protocol used by sender (if available, for security tracking)<tr><td align=top><tt>from_port</tt><td>TCP/UDP port number used by sender (if available, for security tracking)<tr><td align=top><tt>sender_userid</tt><td>Sender's user ID (if available, for security tracking)<tr><td align=top><tt>sender_server</tt><td>Server's host name (if available, for security tracking)<tr><td align=top><tt>sender_time</tt><td>Time/Date message was received from sender (if available, for security tracking)<tr><td align=top><tt>replyto</tt><td>Replies should be sent to this name<tr><td align=top><tt>replyto_ext</tt><td>Replies should be sent to this user number<tr><td align=top><tt>replyto_org</tt><td>Replies should be sent to organization<tr><td align=top><tt>replyto_net_type</tt><td>Replies should be sent to this network type<tr><td align=top><tt>replyto_net_addr</tt><td>Replies should be sent to this network address<tr><td align=top><tt>replyto_agent</tt><td>Replies should be sent to this agent type<tr><td align=top><tt>replyto_list</tt><td>Comma-separated list of mailboxes to reply-to, RFC822-style<tr><td align=top><tt>mime-version</tt><td>MIME Version (optional)<tr><td align=top><tt>content-type</tt><td>MIME Content-Type (optional)<tr><td align=top><tt>summary</tt><td>Message Summary (optional)<tr><td align=top><tt>tags</tt><td>Message Tags (space-delimited, optional)<tr><td align=top><tt>id</tt><td>Message's RFC-822 compliant Message-ID<tr><td align=top><tt>reply_id</tt><td>Message's RFC-822 compliant Reply-ID<tr><td align=top><tt>reverse_path</tt><td>Message's SMTP sender address<tr><td align=top><tt>forward_path</tt><td>Argument to SMTP 'RCPT TO' command<tr><td align=top><tt>path</tt><td>Messages's NNTP path<tr><td align=top><tt>newsgroups</tt><td>Message's NNTP newsgroups header<tr><td align=top><tt>ftn_msgid</tt><td>FidoNet FTS-9 Message-ID<tr><td align=top><tt>ftn_reply</tt><td>FidoNet FTS-9 Reply-ID<tr><td align=top><tt>ftn_area</tt><td>FidoNet FTS-4 echomail AREA tag<tr><td align=top><tt>ftn_flags</tt><td>FidoNet FSC-53 FLAGS<tr><td align=top><tt>ftn_pid</tt><td>FidoNet FSC-46 Program Identifier<tr><td align=top><tt>ftn_tid</tt><td>FidoNet FSC-46 Tosser Identifier<tr><td align=top><tt>ftn_charset</tt><td>FidoNet FTS-5003 Character Set Identifier<tr><td align=top><tt>date</tt><td>RFC-822 formatted date/time<tr><td align=top><tt>attr</tt><td>Attribute bitfield<tr><td align=top><tt>auxattr</tt><td>Auxillary attribute bitfield<tr><td align=top><tt>netattr</tt><td>Network attribute bitfield<tr><td align=top><tt>when_written_time</tt><td>Date/time (in time_t format)<tr><td align=top><tt>when_written_zone</tt><td>Time zone (in SMB format)<tr><td align=top><tt>when_written_zone_offset</tt><td>Time zone in minutes east of UTC<tr><td align=top><tt>when_imported_time</tt><td>Date/time message was imported<tr><td align=top><tt>when_imported_zone</tt><td>Time zone (in SMB format)<tr><td align=top><tt>when_imported_zone_offset</tt><td>Time zone in minutes east of UTC<tr><td align=top><tt>thread_id</tt><td>Thread identifier (originating message number)<tr><td align=top><tt>thread_back</tt><td>Message number that this message is a reply to<tr><td align=top><tt>thread_next</tt><td>Message number of the next reply to the original message in this thread<tr><td align=top><tt>thread_first</tt><td>Message number of the first reply to this message<tr><td align=top><tt>votes</tt><td>Bit-field of votes if ballot, maximum allowed votes per ballot if poll<tr><td align=top><tt>priority</tt><td>Priority value following the <i>X-Priority</i> email header schcme (1 = highest, 3 = normal, 5 = lowest, 0 = unspecified)<tr><td align=top><tt>delivery_attempts</tt><td>Number of failed delivery attempts (e.g. over SMTP)<tr><td align=top><tt>field_list[].type</tt><td>Other SMB header fields (type)<tr><td align=top><tt>field_list[].data</tt><td>Other SMB header fields (data)<tr><td align=top><tt>can_read</tt><td>true if the current user can read this validated or unmoderated message</table><br><i>New in v3.12:</i> The optional <i>client</i> argument is an instance of the <i>Client</i> class to be used for the security log header fields (e.g. sender IP address, hostname, protocol, and port).  As of version 3.16c, the global client object will be used if this is omitted.<br><br><i>New in v3.12:</i> The optional <i>rcpt_list</i> is an array of objects that specifies multiple recipients for a single message (e.g. bulk e-mail). Each object in the array may include the following header properties (described above): <br><i>to</i>, <i>to_ext</i>, <i>to_org</i>, <i>to_net_type</i>, <i>to_net_addr</i>, and <i>to_agent</i>
<tr valign=top><td><b>vote_msg</b><td>boolean<td><tt>MsgBase.vote_msg(object header)
<td>3.17
<td>create a new vote in message base, the <i>header</i> object should contain the following properties:<br><table><tr><td align=top><tt>from</tt><td>Sender's name <i>(required)</i><tr><td align=top><tt>from_ext</tt><td>Sender's user number (if applicable)<tr><td align=top><tt>from_net_type</tt><td>Sender's network type (default: 0 for local)<tr><td align=top><tt>from_net_addr</tt><td>Sender's network address<tr><td align=top><tt>reply_id</tt><td>The Reply-ID of the message being voted on (or specify thread_back)<tr><td align=top><tt>thread_back</tt><td>Message number of the message being voted on<tr><td align=top><tt>attr</tt><td>Should be either MSG_UPVOTE, MSG_DOWNVOTE, or MSG_VOTE (if answer to poll)</table>
<tr valign=top><td><b>add_poll</b><td>boolean<td><tt>MsgBase.add_poll(object header)
<td>3.17
<td>create a new poll in message base, the <i>header</i> object should contain the following properties:<br><table><tr><td align=top><tt>subject</tt><td>Polling question <i>(required)</i><tr><td align=top><tt>from</tt><td>Sender's name <i>(required)</i><tr><td align=top><tt>from_ext</tt><td>Sender's user number (if applicable)<tr><td align=top><tt>from_net_type</tt><td>Sender's network type (default: 0 for local)<tr><td align=top><tt>from_net_addr</tt><td>Sender's network address</table>
<tr valign=top><td><b>close_poll</b><td>boolean<td><tt>MsgBase.close_poll(message number, user name or alias)
<td>3.17
<td>close an existing poll
<tr valign=top><td><b>how_user_voted</b><td>number<td><tt>MsgBase.how_user_voted(message number, user name or alias)
<td>3.17
<td>Returns 0 for no votes, 1 for an up-vote, 2 for a down-vote, or in the case of a poll-response: a bit-field of votes.
<tr valign=top><td><b>dump_msg_header</b><td>array<td><tt>MsgBase.dump_msg_header(object header)
<td>3.17c
<td>dump a message header object to an array of strings for diagnostic uses
</table>
<br>
<table border=1 width=100%>
<caption align=left><b><tt>MsgBase</tt>
<a name=MsgBase_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>error</b><td>string
<td>3.10
<td>last occurred message base error - <small>READ ONLY</small>
<tr valign=top><td><b>status</b><td>number
<td>3.12
<td>return value of last <i>SMB Library</i> function call - <small>READ ONLY</small>
<tr valign=top><td><b>file</b><td>string
<td>3.10
<td>base path and filename of message base - <small>READ ONLY</small>
<tr valign=top><td><b>retry_time</b><td>number
<td>3.10
<td>message base open/lock retry timeout (in seconds)
<tr valign=top><td><b>retry_delay</b><td>number
<td>3.11
<td>delay between message base open/lock retries (in milliseconds)
<tr valign=top><td><b>first_msg</b><td>number
<td>3.10
<td>first message number - <small>READ ONLY</small>
<tr valign=top><td><b>last_msg</b><td>number
<td>3.10
<td>last message number - <small>READ ONLY</small>
<tr valign=top><td><b>total_msgs</b><td>number
<td>3.10
<td>total number of messages - <small>READ ONLY</small>
<tr valign=top><td><b>max_crcs</b><td>number
<td>3.10
<td>maximum number of message CRCs to store (for dupe checking) - <small>READ ONLY</small>
<tr valign=top><td><b>max_msgs</b><td>number
<td>3.10
<td>maximum number of messages before expiration - <small>READ ONLY</small>
<tr valign=top><td><b>max_age</b><td>number
<td>3.10
<td>maximum age (in days) of messages to store - <small>READ ONLY</small>
<tr valign=top><td><b>attributes</b><td>number
<td>3.10
<td>message base attributes - <small>READ ONLY</small>
<tr valign=top><td><b>subnum</b><td>number
<td>3.10
<td>sub-board number (0-based, 65535 for e-mail) - <small>READ ONLY</small>
<tr valign=top><td><b>is_open</b><td>boolean
<td>3.10
<td><i>true</i> if the message base has been opened successfully - <small>READ ONLY</small>
</table>
<h2><a name=MsgBase.cfg>MsgBase.cfg object</a>
<br><font size=-1>Configuration parameters for this message area (<i>sub-boards only</i>) - <small>READ ONLY</small></font>
<font size=-1> - introduced in v3.10</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>MsgBase.cfg</tt>
<a name=MsgBase.cfg_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>index</b><td>undefined
<td>index into sub_list array (or -1 if not in array) <i>(introduced in v3.12)</i>
<tr valign=top><td><b>grp_index</b><td>undefined
<td>group's index into grp_list array <i>(introduced in v3.12)</i>
<tr valign=top><td><b>number</b><td>number
<td>unique number for this sub-board
<tr valign=top><td><b>grp_number</b><td>number
<td>group number
<tr valign=top><td><b>grp_name</b><td>string
<td>group name <i>(introduced in v3.12)</i>
<tr valign=top><td><b>code</b><td>string
<td>sub-board internal code
<tr valign=top><td><b>name</b><td>string
<td>sub-board name
<tr valign=top><td><b>description</b><td>string
<td>sub-board description
<tr valign=top><td><b>qwk_name</b><td>string
<td>sub-board QWK name
<tr valign=top><td><b>newsgroup</b><td>string
<td>newsgroup name (as configured or dymamically generated)
<tr valign=top><td><b>ars</b><td>string
<td>sub-board access requirements
<tr valign=top><td><b>read_ars</b><td>string
<td>sub-board reading requirements
<tr valign=top><td><b>post_ars</b><td>string
<td>sub-board posting requirements
<tr valign=top><td><b>operator_ars</b><td>string
<td>sub-board operator requirements
<tr valign=top><td><b>moderated_ars</b><td>string
<td>sub-board moderated-user requirements (if non-blank)
<tr valign=top><td><b>data_dir</b><td>string
<td>sub-board data storage location
<tr valign=top><td><b>fidonet_origin</b><td>string
<td>FidoNet origin line
<tr valign=top><td><b>qwknet_tagline</b><td>string
<td>QWK Network tagline
<tr valign=top><td><b>settings</b><td>number
<td>toggle options (bitfield) - see <tt>SUB_*</tt> in <tt>sbbsdefs.js</tt> for details
<tr valign=top><td><b>ptridx</b><td>number
<td>index into message scan configuration/pointer file
<tr valign=top><td><b>qwk_conf</b><td>number
<td>QWK conference number
<tr valign=top><td><b>max_crcs</b><td>number
<td>configured maximum number of message CRCs to store (for dupe checking)
<tr valign=top><td><b>max_msgs</b><td>number
<td>configured maximum number of messages before purging
<tr valign=top><td><b>max_age</b><td>number
<td>configured maximum age (in days) of messages before expiration
<tr valign=top><td><b>print_mode</b><td>number
<td>additional print mode flags to use when printing messages - see <tt>P_*</tt> in <tt>sbbsdefs.js</tt> for details
<tr valign=top><td><b>print_mode_neg</b><td>number
<td>print mode flags to <i>negate</i> when printing messages - see <tt>P_*</tt> in <tt>sbbsdefs.js</tt> for details
</table>
<h2><a name=File>File class</a>
<br><font size=-1>Class used for opening, creating, reading, or writing files on the local file system<p>Special features include:</h2><ol type=disc><li>Exclusive-access files (default) or shared files<ol type=circle><li>optional record-locking<li>buffered or non-buffered I/O</ol><li>Support for binary files<ol type=circle><li>native or network byte order (endian)<li>automatic Unix-to-Unix (<i>UUE</i>), yEncode (<i>yEnc</i>) or Base64 encoding/decoding</ol><li>Support for ASCII text files<ol type=circle><li>supports line-based I/O<ol type=square><li>entire file may be read or written as an array of strings<li>individual lines may be read or written one line at a time</ol><li>supports fixed-length records<ol type=square><li>optional end-of-text (<i>etx</i>) character for automatic record padding/termination<li>Synchronet <tt>.dat</tt> files use an <i>etx</i> value of 3 (Ctrl-C)</ol><li>supports <tt>.ini</tt> formated configuration files<ol type=square><li>concept and support of <i>root</i> ini sections added in v3.12</ol><li>optional ROT13 encoding/translation</ol><li>Dynamically-calculated industry standard checksums (e.g. CRC-16, CRC-32, MD5)</ol></font>
<font size=-1> - introduced in v3.10</font>
</h2>
<p>To create a new File object: <tt>var f = new File(<i>filename</i>)</tt></p>
<table border=1 width=100%>
<caption align=left><b><tt>File</tt>
<a name=File_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>open</b><td>boolean<td><tt>File.open([mode=<tt>"w+"</tt>] [,shareable=<tt>false</tt>] [,buffer_length])
<td>3.10
<td>open file, <i>shareable</i> defaults to <i>false</i>, <i>buffer_length</i> defaults to 2048 bytes, mode (default: <tt>'w+'</tt>) specifies the type of access requested for the file, as follows:<br><tt>r&nbsp</tt> open for reading; if the file does not exist or cannot be found, the open call fails<br><tt>w&nbsp</tt> open an empty file for writing; if the given file exists, its contents are destroyed<br><tt>a&nbsp</tt> open for writing at the end of the file (appending); creates the file first if it doesn't exist<br><tt>r+</tt> open for both reading and writing (the file must exist)<br><tt>w+</tt> open an empty file for both reading and writing; if the given file exists, its contents are destroyed<br><tt>a+</tt> open for reading and appending<br><tt>b&nbsp</tt> open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed (e.g. <tt>r+b</tt>)<br><tt>x&nbsp</tt> open a <i>non-shareable</i> file (that must not already exist) for <i>exclusive</i> access <i>(introduced in v3.17)</i><br><br><b>Note:</b> When using the <tt>iniSet</tt> methods to modify a <tt>.ini</tt> file, the file must be opened for both reading <b>and</b> writing.<br><br><b>Note:</b> To open an existing or create a new file for both reading and writing (e.g. updating an <tt>.ini</tt> file) use the <i>exists</i> property like so:<br><tt>file.open(file.exists ? 'r+':'w+');</tt><br><b>Note:</b> When <i>shareable</i> is false, uses nopen() which will lock the file and perform automatic retries.  The lock mode is as follows:<br><tt>r&nbsp</tt> DENYWRITE - Allows other scripts to open the file for reading, but not for writing.<br><tt>w&nbsp</tt> DENYALL - Does not allow other scripts to open the file when <i>shareable</i> is set to true<br><tt>a&nbsp</tt> DENYALL - Does not allow other scripts to open the file when <i>shareable</i> is set to true<br><tt>r+</tt> DENYALL - Does not allow other scripts to open the file when <i>shareable</i> is set to true<br><tt>w+</tt> DENYALL - Does not allow other scripts to open the file when <i>shareable</i> is set to true<br><tt>a+</tt> DENYALL - Does not allow other scripts to open the file when <i>shareable</i> is set to true<br>When <i>shareable</i> is true uses fopen(), and will only attempt to open the file once and will perform no locking.  The behavior when one script has a file opened with <i>shareable</i> set to a different value than is used with a new call is OS specific.  On Windows, the second open will always fail and on *nix, the second open will always succeed.<br>
<tr valign=top><td><b>popen</b><td>boolean<td><tt>File.popen([mode=<tt>"r+"</tt>] [,buffer_length])
<td>3.15
<td>open pipe to command, <i>buffer_length</i> defaults to 2048 bytes, mode (default: <tt>'r+'</tt>) specifies the type of access requested for the file, as follows:<br><tt>r&nbsp</tt> read the programs stdout;<br><tt>w&nbsp</tt> write to the programs stdin<br><tt>r+</tt> open for both reading stdout and writing stdin<br>(<b>only functional on UNIX systems</b>)
<tr valign=top><td><b>close</b><td>void<td><tt>File.close()
<td>3.10
<td>close file
<tr valign=top><td><b>remove</b><td>boolean<td><tt>File.remove()
<td>3.10
<td>remove the file from the disk
<tr valign=top><td><b>clear_error</b><td>boolean<td><tt>File.clear_error()
<td>3.10
<td>clears the current error value (AKA clearError)
<tr valign=top><td><b>flush</b><td>boolean<td><tt>File.flush()
<td>3.10
<td>flush/commit buffers to disk
<tr valign=top><td><b>rewind</b><td>boolean<td><tt>File.rewind()
<td>3.11
<td>repositions the file pointer (<i>position</i>) to the beginning of a file and clears error and end-of-file indicators
<tr valign=top><td><b>truncate</b><td>boolean<td><tt>File.truncate([length=<tt>0</tt>])
<td>3.14
<td>changes the file <i>length</i> (default: 0) and repositions the file pointer (<i>position</i>) to the new end-of-file
<tr valign=top><td><b>lock</b><td>boolean<td><tt>File.lock([offset=<tt>0</tt>] [,length=<i>file_length</i>-<i>offset</i>])
<td>3.10
<td>lock file record for exclusive access (file must be opened <i>shareable</i>)
<tr valign=top><td><b>unlock</b><td>boolean<td><tt>File.unlock([offset=<tt>0</tt>] [,length=<i>file_length</i>-<i>offset</i>])
<td>3.10
<td>unlock file record for exclusive access
<tr valign=top><td><b>read</b><td>string<td><tt>File.read([maxlen=<i>file_length</i>-<i>file_position</i>])
<td>3.10
<td>read a string from file (optionally unix-to-unix or base64 decoding in the process), <i>maxlen</i> defaults to the current length of the file minus the current file position
<tr valign=top><td><b>readln</b><td>string<td><tt>File.readln([maxlen=<tt>512</tt>])
<td>3.10
<td>read a line-feed terminated string, <i>maxlen</i> defaults to 512 characters
<tr valign=top><td><b>readBin</b><td>number<td><tt>File.readBin([bytes=<tt>4</tt> [,count=<tt>1</tt>])
<td>3.10
<td>read one or more binary integers from the file, default number of <i>bytes</i> is 4 (32-bits). if count is not equal to 1, an array is returned (even if no integers were read)
<tr valign=top><td><b>readAll</b><td>array<td><tt>File.readAll([maxlen=<tt>512</tt>])
<td>3.10
<td>read all lines into an array of strings, <i>maxlen</i> defaults to 512 characters
<tr valign=top><td><b>raw_read</b><td>string<td><tt>File.raw_read([maxlen=<i>1</i>])
<td>3.17
<td>read a string from underlying file descriptor. Undefined results when mixed with any other read/write methods except raw_write, including indirect ones. <i>maxlen</i> defaults to one
<tr valign=top><td><b>raw_pollin</b><td>boolean<td><tt>File.raw_pollin([timeout])
<td>3.17
<td>waits up to <i>timeout</i> milliseconds (or forever if timeout is not specified) for data to be available via raw_read().
<tr valign=top><td><b>write</b><td>boolean<td><tt>File.write(text [,length=<i>text_length</i>])
<td>3.10
<td>write a string to the file (optionally unix-to-unix or base64 decoding in the process). If the specified <i>length</i> is longer than the <i>text</i>, the remaining length will be written as NUL bytes.
<tr valign=top><td><b>writeln</b><td>boolean<td><tt>File.writeln([text])
<td>3.10
<td>write a new-line terminated string (a line of text) to the file
<tr valign=top><td><b>writeBin</b><td>boolean<td><tt>File.writeBin(value(s) [,bytes=<tt>4</tt>])
<td>3.10
<td>write one or more binary integers to the file, default number of <i>bytes</i> is 4 (32-bits).If value is an array, writes the entire array to the file.
<tr valign=top><td><b>writeAll</b><td>boolean<td><tt>File.writeAll(array lines)
<td>3.10
<td>write an array of new-line terminated strings (lines of text) to the file
<tr valign=top><td><b>raw_write</b><td>boolean<td><tt>File.raw_write(text)
<td>3.17
<td>write a string to the underlying file descriptor. Undefined results when mixed with any other read/write methods except raw_read, including indirect ones.
<tr valign=top><td><b>printf</b><td>number<td><tt>File.printf(format [,args])
<td>3.10
<td>write a formatted string to the file (ala fprintf) - <small>CAUTION: for experienced C programmers ONLY</small>
<tr valign=top><td><b>iniGetSections</b><td>array<td><tt>File.iniGetSections([prefix=<i>none</i>])
<td>3.11
<td>parse all section names from a <tt>.ini</tt> file (format = '<tt>[section]</tt>') and return the section names as an <i>array of strings</i>, optionally, only those section names that begin with the specified <i>prefix</i>
<tr valign=top><td><b>iniGetKeys</b><td>array<td><tt>File.iniGetKeys([section=<i>root</i>])
<td>3.11
<td>parse all key names from the specified <i>section</i> in a <tt>.ini</tt> file and return the key names as an <i>array of strings</i>. if <i>section</i> is undefined, returns key names from the <i>root</i> section
<tr valign=top><td><b>iniGetValue</b><td>undefined<td><tt>File.iniGetValue(section, key [,default=<i>none</i>])
<td>3.11
<td>parse a key from a <tt>.ini</tt> file and return its value (format = '<tt>key = value</tt>'). returns the specified <i>default</i> value if the key or value is missing or invalid. to parse a key from the <i>root</i> section, pass <i>null</i> for <i>section</i>. Returns a <i>bool</i>, <i>number</i>, <i>string</i>, or an <i>array of strings</i> determined by the type of <i>default</i> value specified. <br><b>Note:</b> To insure that any/all values are returned as a string (e.g. numeric passwords are <b>not</b> returned as a <i>number</i>), pass an empty string ('') for the <i>default</i> value.
<tr valign=top><td><b>iniSetValue</b><td>boolean<td><tt>File.iniSetValue(section, key, [value=<i>none</i>])
<td>3.12
<td>set the specified <i>key</i> to the specified <i>value</i> in the specified <i>section</i> of a <tt>.ini</tt> file. to set a key in the <i>root</i> section, pass <i>null</i> for <i>section</i>. 
<tr valign=top><td><b>iniGetObject</b><td>object<td><tt>File.iniGetObject([section=<i>root</i>] [lowercase=<tt>false</tt>])
<td>3.11
<td>parse an entire section from a .ini file and return all of its keys (optionally lowercased) and values as properties of an object. if <i>section</i> is <tt>null</tt> or <tt>undefined</tt>, returns keys and values from the <i>root</i> section. Returns <i>null</i> if the specified <i>section</i> does not exist in the file or the file has not been opened.
<tr valign=top><td><b>iniSetObject</b><td>boolean<td><tt>File.iniSetObject(section, object)
<td>3.12
<td>write all the properties of the specified <i>object</i> as separate <tt>key=value</tt> pairs in the specified <i>section</i> of a <tt>.ini</tt> file. to write an object in the <i>root</i> section, pass <i>null</i> for <i>section</i>. <br><b>Note:</b> this method does not remove unreferenced keys from an existing section. If your intention is to <i>replace</i> an existing section, use the <tt>iniRemoveSection</tt> function first.
<tr valign=top><td><b>iniGetAllObjects</b><td>array<td><tt>File.iniGetAllObjects([name_property] [,prefix=<i>none</i>] [lowercase=<tt>false</tt>])
<td>3.11
<td>parse all sections from a .ini file and return all (non-<i>root</i>) sections in an array of objects with each section's keys (optionally lowercased) as properties of each object. <i>name_property</i> is the name of the property to create to contain the section's name (optionally lowercased, default is <tt>"name"</tt>), the optional <i>prefix</i> has the same use as in the <tt>iniGetSections</tt> method, if a <i>prefix</i> is specified, it is removed from each section's name
<tr valign=top><td><b>iniSetAllObjects</b><td>boolean<td><tt>File.iniSetAllObjects(object array [,name_property=<tt>"name"</tt>])
<td>3.12
<td>write an array of objects to a .ini file, each object in its own section named after the object's <i>name_property</i> (default: <tt>name</tt>)
<tr valign=top><td><b>iniRemoveKey</b><td>boolean<td><tt>File.iniRemoveKey(section, key)
<td>3.14
<td>remove specified <i>key</i> from specified <i>section</i> in <tt>.ini</tt> file.
<tr valign=top><td><b>iniRemoveSection</b><td>boolean<td><tt>File.iniRemoveSection(section)
<td>3.14
<td>remove specified <i>section</i> from <tt>.ini</tt> file.
</table>
<br>
<table border=1 width=100%>
<caption align=left><b><tt>File</tt>
<a name=File_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>name</b><td>string
<td>3.10
<td>filename specified in constructor - <small>READ ONLY</small>
<tr valign=top><td><b>mode</b><td>string
<td>3.10
<td>mode string specified in <i>open</i> call - <small>READ ONLY</small>
<tr valign=top><td><b>exists</b><td>boolean
<td>3.10
<td><i>true</i> if the file is open or exists (case-insensitive) - <small>READ ONLY</small>
<tr valign=top><td><b>is_open</b><td>boolean
<td>3.10
<td><i>true</i> if the file has been opened successfully - <small>READ ONLY</small>
<tr valign=top><td><b>eof</b><td>boolean
<td>3.10
<td><i>true</i> if the current file position is at the <i>end of file</i> - <small>READ ONLY</small>
<tr valign=top><td><b>error</b><td>number
<td>3.10
<td>the last occurred error value (use <i>clear_error</i> to clear) - <small>READ ONLY</small>
<tr valign=top><td><b>descriptor</b><td>number
<td>3.10
<td>the open file descriptor (advanced use only) - <small>READ ONLY</small>
<tr valign=top><td><b>etx</b><td>number
<td>3.10
<td>end-of-text character (advanced use only), if non-zero used by <i>read</i>, <i>readln</i>, and <i>write</i>
<tr valign=top><td><b>debug</b><td>boolean
<td>3.10
<td>set to <i>true</i> to enable debug log output
<tr valign=top><td><b>position</b><td>number
<td>3.10
<td>the current file position (offset in bytes), change value to seek within file
<tr valign=top><td><b>date</b><td>number
<td>3.11
<td>last modified date/time (in time_t format)
<tr valign=top><td><b>length</b><td>number
<td>3.10
<td>the current length of the file (in bytes)
<tr valign=top><td><b>attributes</b><td>number
<td>3.10
<td>file type/mode flags (i.e. <tt>struct stat.st_mode</tt> value, compatible with <tt>file_chmod()</tt>)
<tr valign=top><td><b>network_byte_order</b><td>boolean
<td>3.11
<td>set to <i>true</i> if binary data is to be written and read in Network Byte Order (big end first)
<tr valign=top><td><b>rot13</b><td>boolean
<td>3.11
<td>set to <i>true</i> to enable automatic ROT13 translation of text
<tr valign=top><td><b>uue</b><td>boolean
<td>3.11
<td>set to <i>true</i> to enable automatic Unix-to-Unix encode and decode on <tt>read</tt> and <tt>write</tt> calls
<tr valign=top><td><b>yenc</b><td>boolean
<td>3.11
<td>set to <i>true</i> to enable automatic yEnc encode and decode on <tt>read</tt> and <tt>write</tt> calls
<tr valign=top><td><b>base64</b><td>boolean
<td>3.11
<td>set to <i>true</i> to enable automatic Base64 encode and decode on <tt>read</tt> and <tt>write</tt> calls
<tr valign=top><td><b>crc16</b><td>number
<td>3.11
<td>calculated 16-bit CRC of file contents - <small>READ ONLY</small>
<tr valign=top><td><b>crc32</b><td>number
<td>3.11
<td>calculated 32-bit CRC of file contents - <small>READ ONLY</small>
<tr valign=top><td><b>chksum</b><td>number
<td>3.11
<td>calculated 32-bit checksum of file contents - <small>READ ONLY</small>
<tr valign=top><td><b>md5_hex</b><td>undefined
<td>3.11
<td>calculated 128-bit MD5 digest of file contents as hexadecimal string - <small>READ ONLY</small>
<tr valign=top><td><b>md5_base64</b><td>undefined
<td>3.11
<td>calculated 128-bit MD5 digest of file contents as base64-encoded string - <small>READ ONLY</small>
<tr valign=top><td><b>ini_key_len</b><td>number
<td>3.17
<td>ini style: minimum key length (for left-justified white-space padded keys)
</table>
<h2><a name=Queue>Queue class</a>
<br><font size=-1>Class for bi-directional message queues. Used for inter-thread/module communications.</font>
<font size=-1> - introduced in v3.12</font>
</h2>
<p>To create a new (named) Queue object: <tt>var q = new Queue(<i>name</i>)</tt></p>
<table border=1 width=100%>
<caption align=left><b><tt>Queue</tt>
<a name=Queue_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>poll</b><td>undefined<td><tt>Queue.poll([timeout=<tt>0</tt>])
<td>3.12
<td>wait for any value to be written to the queue for up to <i>timeout</i> milliseconds (default: <i>0</i>), returns <i>true</i> or the <i>name</i> (string) of the value waiting (if it has one), or <i>false</i> if no values are waiting
<tr valign=top><td><b>read</b><td>undefined<td><tt>Queue.read([string name] or [timeout=<tt>0</tt>])
<td>3.13
<td>read a value from the queue, if <i>name</i> not specified, reads next value from the bottom of the queue (waiting up to <i>timeout</i> milliseconds)
<tr valign=top><td><b>peek</b><td>undefined<td><tt>Queue.peek([timeout=<tt>0</tt>])
<td>3.13
<td>peek at the value at the bottom of the queue, wait up to <i>timeout</i> milliseconds for any value to be written (default: <i>0</i>)
<tr valign=top><td><b>write</b><td>boolean<td><tt>Queue.write(value [,name=<i>none</i>])
<td>3.12
<td>write a value (optionally named) to the queue
</table>
<br>
<table border=1 width=100%>
<caption align=left><b><tt>Queue</tt>
<a name=Queue_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>name</b><td>undefined
<td>3.12
<td>name of the queue (if it has one)
<tr valign=top><td><b>data_waiting</b><td>boolean
<td>3.12
<td><i>true</i> if data is waiting to be read from queue
<tr valign=top><td><b>read_level</b><td>number
<td>3.12
<td>number of values in the read queue
<tr valign=top><td><b>write_level</b><td>number
<td>3.12
<td>number of values in the write queue
<tr valign=top><td><b>owner</b><td>boolean
<td>3.16
<td><i>true</i> if current thread is the owner/creator of the queue
<tr valign=top><td><b>orphan</b><td>boolean
<td>3.17c
<td><i>true</i> if the owner of the queue has detached from the queue
</table>
<h2><a name=Socket>Socket class</a>
<br><font size=-1>Class used for TCP/IP socket communications</font>
<font size=-1> - introduced in v3.10</font>
</h2>
<p>To create a new Socket object: <tt>load('sockdefs.js'); var s = new Socket(<i>type</i>, <i>protocol</i> ,<i>ipv6</i>=false)</tt><br>where <i>type</i> = <tt>SOCK_STREAM</tt> for TCP (default) or <tt>SOCK_DGRAM</tt> for UDP<br>and <i>protocol</i> (optional) = the name of the protocol or service the socket is to be used for<br>To create a socket from an existing socket descriptor: <tt>var s = new Socket(true, <i>descriptor</i>)</tt><br>where <i>descriptor</i> is the numerical value of an existing valid socket descriptor</p>
<table border=1 width=100%>
<caption align=left><b><tt>Socket</tt>
<a name=Socket_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>close</b><td>void<td><tt>Socket.close()
<td>3.10
<td>close (shutdown) the socket immediately
<tr valign=top><td><b>bind</b><td>boolean<td><tt>Socket.bind([port] [,ip_address])
<td>3.11
<td>bind socket to a TCP or UDP <i>port</i> (number or service name), optionally specifying a network interface (via <i>ip_address</i>)
<tr valign=top><td><b>connect</b><td>boolean<td><tt>Socket.connect(host, port [,timeout=<tt>10.0</tt>])
<td>3.11
<td>connect to a remote port (number or service name) on the specified host (IP address or host name), default <i>timeout</i> value is <i>10.0</i> (seconds)
<tr valign=top><td><b>listen</b><td>boolean<td><tt>Socket.listen()
<td>3.10
<td>place socket in a state to listen for incoming connections (use before an accept)
<tr valign=top><td><b>accept</b><td>object<td><tt>Socket.accept()
<td>3.10
<td>accept an incoming connection, returns a new <i>Socket</i> object representing the new connection
<tr valign=top><td><b>send</b><td>number<td><tt>Socket.send(data)
<td>3.10
<td>send a string (AKA write).  Returns the number of bytes sent or undefined if an error occured.  Versions before 3.17 returned a bool true if all bytes were sent and false otherwise.
<tr valign=top><td><b>sendline</b><td>boolean<td><tt>Socket.sendline(data)
<td>3.17
<td>send a string (AKA write) with a carriage return line feed appended
<tr valign=top><td><b>sendto</b><td>boolean<td><tt>Socket.sendto(data, address, port)
<td>3.10
<td>send data to a specific host (IP address or host name) and port (number or service name), for UDP sockets
<tr valign=top><td><b>sendfile</b><td>boolean<td><tt>Socket.sendfile(path/filename)
<td>3.10
<td>send an entire file over the socket
<tr valign=top><td><b>sendBin</b><td>boolean<td><tt>Socket.sendBin(value [,bytes=<tt>4</tt>])
<td>3.11
<td>send a binary integer over the socket, default number of bytes is 4 (32-bits)
<tr valign=top><td><b>recv</b><td>string<td><tt>Socket.recv([maxlen=<tt>512</tt>, [timeout_sec=<tt>120</tt>]])
<td>3.10
<td>receive a string, default maxlen is 512 characters (AKA read)
<tr valign=top><td><b>peek</b><td>string<td><tt>Socket.peek([maxlen=<tt>512</tt>])
<td>3.10
<td>receive a string, default maxlen is 512 characters, leaves string in receive buffer (TLS sockets will never return more than one byte)
<tr valign=top><td><b>recvline</b><td>string<td><tt>Socket.recvline([maxlen=<tt>512</tt>] [,timeout=<tt>30.0</tt>])
<td>3.10
<td>receive a line-feed terminated string, default maxlen is 512 characters, default timeout is 30 seconds (AKA readline and readln)
<tr valign=top><td><b>recvfrom</b><td>object<td><tt>Socket.recvfrom([binary=<tt>false</tt>] [,maxlen=<tt>512</tt> or int_size=<tt>4</tt>])
<td>3.11
<td>receive data (string or integer) from a socket (typically UDP)<p>returns object with <i>ip_address</i> and <i>port</i> of sender along with <i>data</i> properties<p><i>binary</i> defaults to <i>false</i>, <i>maxlen</i> defaults to 512 chars, <i>int_size</i> defaults to 4 bytes (32-bits)
<tr valign=top><td><b>recvBin</b><td>number<td><tt>Socket.recvBin([bytes=<tt>4</tt>])
<td>3.11
<td>receive a binary integer from the socket, default number of bytes is 4 (32-bits)
<tr valign=top><td><b>getoption</b><td>number<td><tt>Socket.getoption(option)
<td>3.10
<td>get socket option value, option may be socket option name (see <tt>sockopts</tt> in <tt>sockdefs.js</tt>) or number
<tr valign=top><td><b>setoption</b><td>boolean<td><tt>Socket.setoption(option, value)
<td>3.10
<td>set socket option value, option may be socket option name (see <tt>sockopts</tt> in <tt>sockdefs.js</tt>) or number
<tr valign=top><td><b>ioctl</b><td>number<td><tt>Socket.ioctl(command [,argument=<tt>0</tt>])
<td>3.10
<td>send socket IOCTL (advanced)
<tr valign=top><td><b>poll</b><td>number<td><tt>Socket.poll([timeout=<tt>0</tt>] [,write=<tt>false</tt>])
<td>3.10
<td>poll socket for read or write ability (default is <i>read</i>), default timeout value is 0.0 seconds (immediate timeout)
</table>
<br>
<table border=1 width=100%>
<caption align=left><b><tt>Socket</tt>
<a name=Socket_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>error</b><td>number
<td>3.11
<td>error status for the last socket operation that failed - <small>READ ONLY</small>
<tr valign=top><td><b>error_str</b><td>string
<td>3.18
<td>error description for the last socket operation that failed - <small>READ ONLY</small>
<tr valign=top><td><b>is_connected</b><td>boolean
<td>3.10
<td><i>true</i> if socket is in a connected state - <small>READ ONLY</small>
<tr valign=top><td><b>is_writeable</b><td>boolean
<td>3.11
<td><i>true</i> if socket can accept written data - Setting to false will shutdown the write end of the socket.
<tr valign=top><td><b>is_writable</b><td>boolean
<td>3.12
<td>alias for is_writeable
<tr valign=top><td><b>data_waiting</b><td>boolean
<td>3.10
<td><i>true</i> if data is waiting to be read from socket - <small>READ ONLY</small>
<tr valign=top><td><b>nread</b><td>number
<td>3.10
<td>number of bytes waiting to be read - TLS sockets will never return more than 1 - <small>READ ONLY</small>
<tr valign=top><td><b>debug</b><td>number
<td>3.10
<td>enable debug logging
<tr valign=top><td><b>descriptor</b><td>number
<td>3.10
<td>socket descriptor (advanced uses only)
<tr valign=top><td><b>nonblocking</b><td>boolean
<td>3.10
<td>use non-blocking operation (default is <i>false</i>)
<tr valign=top><td><b>local_ip_address</b><td>string
<td>3.10
<td>local IP address (string in dotted-decimal format)
<tr valign=top><td><b>local_port</b><td>number
<td>3.10
<td>local TCP or UDP port number
<tr valign=top><td><b>remote_ip_address</b><td>string
<td>3.10
<td>remote IP address (string in dotted-decimal format)
<tr valign=top><td><b>remote_port</b><td>number
<td>3.10
<td>remote TCP or UDP port number
<tr valign=top><td><b>type</b><td>number
<td>3.10
<td>socket type, <tt>SOCK_STREAM</tt> (TCP) or <tt>SOCK_DGRAM</tt> (UDP)
<tr valign=top><td><b>family</b><td>number
<td>3.18
<td>socket protocol family, <tt>PF_INET</tt> (IPv4) or <tt>PF_INET6</tt> (IPv6)
<tr valign=top><td><b>network_byte_order</b><td>boolean
<td>3.11
<td><i>true</i> if binary data is to be sent in Network Byte Order (big end first), default is <i>true</i>
<tr valign=top><td><b>ssl_session</b><td>boolean
<td>3.16
<td>set to <i>true</i> to enable SSL as a client on the socket
<tr valign=top><td><b>ssl_server</b><td>boolean
<td>3.16
<td>set to <i>true</i> to enable SSL as a server on the socket
<tr valign=top><td><b>option_list</b><td>object
<td>N/A
<td>array of socket option names supported by the current platform
</table>
<h2><a name=ConnectedSocket>ConnectedSocket class</a>
<br><font size=-1>Class used for outgoing TCP/IP socket communications</font>
<font size=-1> - introduced in v3.17</font>
</h2>
<p>To create a new ConnectedSocket object: <tt>load('sockdefs.js'); var s = new ConnectedSocket(<i>hostname</i>, <i>port</i>, {domain:<i>domain</i>, proto:<i>proto</i> ,type:<i>type</i>, protocol:<i>protocol</i>, timeout:<i>timeout</i>, bindport:<i>port</i>, bindaddrs:<i>bindaddrs</i>})</tt><br>where <i>domain</i> (optional) = <tt>PF_UNSPEC</tt> (default) for IPv4 or IPv6, <tt>PF_INET</tt> for IPv4, or <tt>PF_INET6</tt> for IPv6<br><i>proto</i> (optional) = <tt>IPPROTO_IP</tt> (default)<br><i>type</i> (optional) = <tt>SOCK_STREAM</tt> for TCP (default) or <tt>SOCK_DGRAM</tt> for UDP<br><i>protocol</i> (optional) = the name of the protocol or service the socket is to be used for<br><i>timeout</i> (optional) = 10 (default) the number of seconds to wait for each connect() call to complete.<br><i>bindport</i> (optional) = the name or number of the source port to bind to<br><i>bindaddrs</i> (optional) = the name or number of the source addresses to bind to.  The first of each IPv4 or IPv6 type is used for that family.<br></p>
<h2><a name=ListeningSocket>ListeningSocket class</a>
<br><font size=-1>Class used for incoming TCP/IP socket communications</font>
<font size=-1> - introduced in v3.17</font>
</h2>
<p>To create a new ListeningSocket object: <tt>load('sockdefs.js'); var s = new ListeningSocket(<i>interface</i>, <i>port</i> ,<i>protocol</i>, {domain:<i>domain</i>, type:<i>type</i>, proto:<i>proto</i>, retry_count:<i>retry_count</i>, retry_delay:<i>retry_delay</i>})</tt><br>where <i>interface</i> = A array or strings or a single string of hostnames or address optionally including a :port suffix<br><i>port</i> = a port to use when the interface doesn't specify one<br><i>protocol</i> = protocol name, used for socket options and logging.<br><i>domain</i> (optional) = <tt>PF_UNSPEC</tt> (default) for IPv4 or IPv6, <tt>AF_INET</tt> for IPv4, or <tt>AF_INET6</tt> for IPv6<br><i>proto</i> (optional) = <tt>IPPROTO_IP</tt> (default)<br><i>type</i> (optional) = <tt>SOCK_STREAM</tt> for TCP (default) or <tt>SOCK_DGRAM</tt> for UDP<br><i>retry_count</i> (optional) = <tt>0</tt> (default) number of times to retry binding<br>and <i>retry_delay</i> (optional) = <tt>15</tt> (default) seconds to wait before a retry<br></p>
<h2><a name=COM>COM class</a>
<br><font size=-1>Class used for serial port communications</font>
<font size=-1> - introduced in v3.15b</font>
</h2>
<p>To create a new COM object: var c = new COM('<i>device</i>')</tt><br>where <i>device</i> = <tt>COMx</tt> (e.g. COM1) for Win32 or <tt>/dev/ttyXY</tt> for *nix (e.g. /dev/ttyu0)</p>
<table border=1 width=100%>
<caption align=left><b><tt>COM</tt>
<a name=COM_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>close</b><td>void<td><tt>COM.close()
<td>3.15
<td>close the port immediately
<tr valign=top><td><b>open</b><td>boolean<td><tt>COM.open()
<td>3.15
<td>connect to a COM port
<tr valign=top><td><b>send</b><td>boolean<td><tt>COM.send(data)
<td>3.15
<td>send a string (AKA write)
<tr valign=top><td><b>sendfile</b><td>boolean<td><tt>COM.sendfile(path/filename)
<td>3.15
<td>send an entire file over the port
<tr valign=top><td><b>sendBin</b><td>boolean<td><tt>COM.sendBin(value [,bytes=<tt>4</tt>])
<td>3.15
<td>send a binary integer over the port, default number of bytes is 4 (32-bits)
<tr valign=top><td><b>recv</b><td>string<td><tt>COM.recv([maxlen=<tt>512</tt> [,timeout=<tt>30</tt>]])
<td>3.15
<td>receive a string, default maxlen is 512 characters, default timeout is 30 seconds (AKA read)
<tr valign=top><td><b>recvline</b><td>string<td><tt>COM.recvline([maxlen=<tt>512</tt>] [,timeout=<tt>30.0</tt>])
<td>3.15
<td>receive a line-feed terminated string, default maxlen is 512 characters, default timeout is 30 seconds (AKA readline and readln)
<tr valign=top><td><b>recvBin</b><td>number<td><tt>COM.recvBin([bytes=<tt>4</tt> [,timeout=<tt>30</tt>])
<td>3.15
<td>receive a binary integer from the port, default number of bytes is 4 (32-bits), default timeout is 30 seconds
</table>
<br>
<table border=1 width=100%>
<caption align=left><b><tt>COM</tt>
<a name=COM_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>error</b><td>number
<td>3.15
<td>error status for the last COM operation that failed - <small>READ ONLY</small>
<tr valign=top><td><b>is_open</b><td>boolean
<td>3.15
<td><i>true</i> if port is in a connected state - <small>READ ONLY</small>
<tr valign=top><td><b>debug</b><td>boolean
<td>3.15
<td>enable debug logging
<tr valign=top><td><b>descriptor</b><td>number
<td>3.15
<td>COM handle (advanced uses only)
<tr valign=top><td><b>network_byte_order</b><td>boolean
<td>3.15
<td><i>true</i> if binary data is to be sent in Network Byte Order (big end first), default is <i>true</i>
<tr valign=top><td><b>baud_rate</b><td>number
<td>3.15
<td>COM port Baud rate
<tr valign=top><td><b>device</b><td>string
<td>3.15
<td>Device name
<tr valign=top><td><b>dtr</b><td>boolean
<td>3.15
<td>Data Terminal Ready
<tr valign=top><td><b>cts</b><td>boolean
<td>3.15
<td>Clear To Send
<tr valign=top><td><b>dsr</b><td>boolean
<td>3.15
<td>Data Set Ready
<tr valign=top><td><b>ring</b><td>boolean
<td>3.15
<td>Ring Indicator
<tr valign=top><td><b>dcd</b><td>boolean
<td>3.15
<td>Data Carrier Detect
</table>
<h2><a name=CryptContext>CryptContext class</a>
<br><font size=-1>Class used for encryption/decryption</font>
<font size=-1> - introduced in v3.16b</font>
</h2>
<p>To create a new CryptContext object: var c = new CryptContext('<i>algorithm</i>')</tt><br>where <i>algorithm</i> is a property of CryptContext.ALGO</p>
<table border=1 width=100%>
<caption align=left><b><tt>CryptContext</tt>
<a name=CryptContext_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>generate_key</b><td>void<td><tt>CryptContext.generate_key()
<td>3.16
<td>Generate a new key for the context.
<tr valign=top><td><b>set_key</b><td>void<td><tt>CryptContext.set_key(key_str)
<td>3.16
<td>Set the key for the context directly.
<tr valign=top><td><b>derive_key</b><td>void<td><tt>CryptContext.derive_key(keying_data)
<td>3.16
<td>Derive the key from the keying data using keying_algo, keying_iterations, and keying_salt.
<tr valign=top><td><b>encrypt</b><td>string<td><tt>CryptContext.encrypt(plaintext)
<td>3.16
<td>Encrypt the string and return as a new string.
<tr valign=top><td><b>decrypt</b><td>string<td><tt>CryptContext.decrypt(ciphertext)
<td>3.16
<td>Decrypt the string and return as a new string.
<tr valign=top><td><b>create_signature</b><td>string<td><tt>CryptContext.create_signature(sigContext)
<td>3.16
<td>Create a signature signed with the sigContext CryptContext object.
</table>
<br>
<table border=1 width=100%>
<caption align=left><b><tt>CryptContext</tt>
<a name=CryptContext_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>algo</b><td>number
<td>3.16
<td>Algorithm constant (CryptContext.ALGO.XXX):<ul class="showList">
<li>CryptContext.ALGO.NONE</li>
<li>CryptContext.ALGO.DES</li>
<li>CryptContext.ALGO.3DES</li>
<li>CryptContext.ALGO.IDEA</li>
<li>CryptContext.ALGO.CAST</li>
<li>CryptContext.ALGO.RC2</li>
<li>CryptContext.ALGO.RC4</li>
<li>CryptContext.ALGO.AES</li>
<li>CryptContext.ALGO.DH</li>
<li>CryptContext.ALGO.RSA</li>
<li>CryptContext.ALGO.DSA</li>
<li>CryptContext.ALGO.ELGAMAL</li>
<li>CryptContext.ALGO.ECDSA</li>
<li>CryptContext.ALGO.ECDH</li>
<li>CryptContext.ALGO.MD5</li>
<li>CryptContext.ALGO.SHA1</li>
<li>CryptContext.ALGO.SHA2</li>
<li>CryptContext.ALGO.SHAng</li>
<li>CryptContext.ALGO.HMAC-SHA1</li>
<li>CryptContext.ALGO.HMAC-SHA2</li>
<li>CryptContext.ALGO.HMAC-SHAng</li></ul>
<tr valign=top><td><b>blocksize</b><td>number
<td>3.16
<td>Cipher block size in bytes
<tr valign=top><td><b>hashvalue</b><td>undefined
<td>3.16
<td>Output of hasing algorithms (ie: MD5, SHA1, etc)
<tr valign=top><td><b>iv</b><td>undefined
<td>3.16
<td>Cipher IV
<tr valign=top><td><b>ivsize</b><td>number
<td>3.16
<td>Cipher IV size in bytes
<tr valign=top><td><b>keying_algo</b><td>undefined
<td>3.16
<td>The keying algorithm used to derive the key
<tr valign=top><td><b>keying_iterations</b><td>number
<td>3.16
<td>The number of iterates used to derive the key
<tr valign=top><td><b>keying_salt</b><td>undefined
<td>3.16
<td>The salt value used to derive an encryption key from a key (Length must be between 8 and 64)
<tr valign=top><td><b>keysize</b><td>number
<td>3.16
<td>Key size in bytes
<tr valign=top><td><b>label</b><td>undefined
<td>3.16
<td>Key label
<tr valign=top><td><b>mode</b><td>number
<td>3.16
<td>Mode constant (CryptContext.MODE.XXX):<ul class="showList">
<li>CryptContext.MODE.None</li>
<li>CryptContext.MODE.ECB</li>
<li>CryptContext.MODE.CBC</li>
<li>CryptContext.MODE.CFB</li>
<li>CryptContext.MODE.GCM</li></ul>
<tr valign=top><td><b>algo_name</b><td>string
<td>3.16
<td>Algorithm name
<tr valign=top><td><b>mode_name</b><td>string
<td>3.16
<td>Mode name
</table>
<h2><a name=CryptKeyset>CryptKeyset class</a>
<br><font size=-1>Class used for storing CryptContext keys</font>
<font size=-1> - introduced in v3.16b</font>
</h2>
<p>To create a new CryptKeyset object: var c = new CryptKeyset('<i>filename</i>' [ <i>opts = CryptKeyset.KEYOPT.NONE</i> ])</tt><br> where <i>filename</i> is the name of the file to create, and <i>opts</i> is a value from CryptKeyset.KEYOPT</p>
<table border=1 width=100%>
<caption align=left><b><tt>CryptKeyset</tt>
<a name=CryptKeyset_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>add_private_key</b><td>void<td><tt>CryptKeyset.add_private_key(CryptContext, password)
<td>3.16
<td>Add a private key to the keyset, encrypting it with <password>.
<tr valign=top><td><b>add_public_key</b><td>void<td><tt>CryptKeyset.add_public_key(CryptCert)
<td>3.16
<td>Add a public key (certificate) to the keyset.
<tr valign=top><td><b>close</b><td>void<td><tt>CryptKeyset.close()
<td>3.16
<td>Close the keyset.
<tr valign=top><td><b>delete_key</b><td>void<td><tt>CryptKeyset.delete_key(label)
<td>3.16
<td>Delete the key with <label> from the keyset.
<tr valign=top><td><b>get_private_key</b><td>object<td><tt>CryptKeyset.get_private_key(label, password)
<td>3.16
<td>Returns a CryptContext from the private key with <label> encrypted with <password>.
<tr valign=top><td><b>get_public_key</b><td>object<td><tt>CryptKeyset.get_public_key(label)
<td>3.16
<td>Returns a CryptCert from the public key with <label>.
</table>
<h2><a name=conio>conio object</a>
<br><font size=-1>Console Input/Output Object (DOS conio library functionality for jsexec)</font>
<font size=-1> - introduced in v3.15</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>conio</tt>
<a name=conio_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>init</b><td>boolean<td><tt>conio.init([mode])
<td>3.15
<td>Initializes the conio library and creates a window if needed.  Mode is a string with one of the following values:<br><table><tr><td>"AUTO" (default)</td><td>Automatically select the "best" output mode.</td></tr><tr><td><tr><td>"ANSI"</td><td>Use ANSI escape sequences directly</td></tr><tr><td><tr><td>"STDIO"</td><td>Use stdio, worst, but most compatible mode.</td></tr><tr><td><tr><td>"X"</td><td>Use X11 output *nix only)</td></tr><tr><td><tr><td>"CONIO"</td><td>Use the native conio library (Windows only)</td></tr><tr><td><tr><td>"CONIO_FULLSCREEN"</td><td>Use the native conio library and request full-screen (full-screen does not work on all versions of Windows) (Windows only)</td></tr><tr><td><tr><td>"CURSES"</td><td>Use the curses terminal library (*nix only)</td></tr><tr><td><tr><td>"CURSES_IBM"</td><td>Use the curses terminal library and write extended ASCII characters directly as-is, assuming the terminal is using CP437. (*nix only)</td></tr><tr><td><tr><td>"CURSES_ASCII"</td><td>Use the curses terminal library and write US-ASCII characters only. (*nix only)</td></tr><tr><td><tr><td>"SDL"</td><td>Use the SDL library for output.</td></tr><tr><td><tr><td>"SDL_FULLSCREEN"</td><td>Use the SDL library for output (fullscreen).</td></tr><tr><td></table>
<tr valign=top><td><b>suspend</b><td>void<td><tt>conio.suspend()
<td>3.15
<td>Suspends conio in CONIO or CURSES modes so the terminal can be used for other things.
<tr valign=top><td><b>clreol</b><td>void<td><tt>conio.clreol()
<td>3.15
<td>Clear to end of line
<tr valign=top><td><b>clrscr</b><td>void<td><tt>conio.clrscr()
<td>3.15
<td>Clears the screen
<tr valign=top><td><b>wscroll</b><td>void<td><tt>conio.wscroll()
<td>3.15
<td>Scrolls the currently defined window up by one line.
<tr valign=top><td><b>delline</b><td>void<td><tt>conio.delline()
<td>3.15
<td>Deletes the current line and moves lines below up by one line.
<tr valign=top><td><b>insline</b><td>void<td><tt>conio.insline()
<td>3.15
<td>Inserts a new blank line on the current line and scrolls lines below down to make room.
<tr valign=top><td><b>normvideo</b><td>void<td><tt>conio.normvideo()
<td>3.15
<td>Sets the current attribute to "normal" (light grey on black)
<tr valign=top><td><b>getch</b><td>number<td><tt>conio.getch()
<td>3.15
<td>Waits for and returns a character from the user.  Extended keys are returned as two characters.
<tr valign=top><td><b>getche</b><td>number<td><tt>conio.getche()
<td>3.15
<td>Waits for a character from the user, then echos it.  Extended keys can not be returned and are lost.
<tr valign=top><td><b>beep</b><td>void<td><tt>conio.beep()
<td>3.15
<td>Beeps.
<tr valign=top><td><b>getfont</b><td>number<td><tt>conio.getfont(fnum)
<td>3.15
<td>Returns the current font ID or -1 if fonts aren't supported.
<tr valign=top><td><b>hidemouse</b><td>number<td><tt>conio.hidemouse()
<td>3.15
<td>Hides the mouse cursor.  Returns -1 if it cannot be hidden.
<tr valign=top><td><b>showmouse</b><td>number<td><tt>conio.showmouse()
<td>3.15
<td>Shows the mouse cursor.  Returns -1 if it cannot be shown.
<tr valign=top><td><b>setcursortype</b><td>void<td><tt>conio.setcursortype(type)
<td>3.15
<td>Sets the cursor type.  Legal values:<br><table><tr><td>0</td><td>No cursor</td></tr><tr><td>1</td><td>Solid cursor (fills whole cell)</td></tr><tr><td>2</td><td>Normal cursor</td></tr></table>
<tr valign=top><td><b>gotoxy</b><td>void<td><tt>conio.gotoxy(x, y)
<td>3.15
<td>Moves the cursor to the given x/y position.
<tr valign=top><td><b>putch</b><td>number<td><tt>conio.putch(charcode)
<td>3.15
<td>Puts the character with the specified ASCII character on the screen and advances the cursor.  Returns the character code passed in.
<tr valign=top><td><b>ungetch</b><td>number<td><tt>conio.ungetch(charcode)
<td>3.15
<td>Pushes the specified charcode into the input buffer.  The next getch() call will get this character.
<tr valign=top><td><b>loadfont</b><td>void<td><tt>conio.loadfont(filename)
<td>3.15
<td>Loads the filename as the current font.  Returns -1 on failure.
<tr valign=top><td><b>settitle</b><td>void<td><tt>conio.settitle(title)
<td>3.15
<td>Sets the window title if possible.
<tr valign=top><td><b>setname</b><td>void<td><tt>conio.setname(name)
<td>3.15
<td>Sets the application name.  In some modes, this overwrites the window title.
<tr valign=top><td><b>cputs</b><td>void<td><tt>conio.cputs(string)
<td>3.15
<td>Outputs string to the console.
<tr valign=top><td><b>setfont</b><td>number<td><tt>conio.setfont(font [, force, fnum])
<td>3.15
<td>Sets a current font to the specified font.  If force is set, will change video modes if the current one callot use the specified font.  fnum selects which current font to change:<br><table><tr><td>0</td><td>Default font</td></tr><tr><td>1</td><td>Main font</td></tr><tr><td>2</td><td>First alternate font</td></tr><tr><td>3</td><td>Second alternate font</td></tr><tr><td>4</td><td>Third alternate font</td></tr></table><br>Returns -1 on failure
<tr valign=top><td><b>getpass</b><td>string<td><tt>conio.getpass(prompt)
<td>3.15
<td>Prompts for a password, and waits for it to be entered.  Characters are not echoed to the screen.
<tr valign=top><td><b>window</b><td>void<td><tt>conio.window(start_x, start_y, end_x, end_y)
<td>3.15
<td>Sets the current window.
<tr valign=top><td><b>cgets</b><td>void<td><tt>conio.cgets(max_len)
<td>3.15
<td>Inputs a string, echoing as it's typed, with the specified max_len (up to 255).
<tr valign=top><td><b>movetext</b><td>void<td><tt>conio.movetext(start_x, start_y, end_x, end_y, dest_x, dest_y)
<td>3.15
<td>Copies the specified screen contents to dest_x/dest_y.
<tr valign=top><td><b>puttext</b><td>boolean<td><tt>conio.puttext(start_x, start_y, end_x, end_y, bytes)
<td>3.15
<td>Puts the contents of the bytes array onto the screen filling the specified rectange.  The array is a sequences if integers between 0 and 255 specifying first the ascii character code, then the attribute for that character.
<tr valign=top><td><b>gettext</b><td>array<td><tt>conio.gettext(start_x, start_y, end_x, end_y)
<td>3.15
<td>Returns an array containing the characters and attributes for the specified rectangle.
</table>
<br>
<table border=1 width=100%>
<caption align=left><b><tt>conio</tt>
<a name=conio_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>wscroll</b><td>boolean
<td>3.15
<td>Allows windows to scroll
<tr valign=top><td><b>directvideo</b><td>boolean
<td>3.15
<td>Enables direct video writes (does nothing)
<tr valign=top><td><b>hold_update</b><td>boolean
<td>3.15
<td>Do not update the screen when characters are printed
<tr valign=top><td><b>puttext_can_move</b><td>boolean
<td>3.15
<td>Calling puttext() (and some other things implemented using it) can move the cursor position
<tr valign=top><td><b>mode</b><td>number
<td>3.15
<td>The current video mode
<tr valign=top><td><b>mouse</b><td>boolean
<td>3.15
<td>
<tr valign=top><td><b>ESCDELAY</b><td>number
<td>3.15
<td>Delay in MS after getting an escape character before assuming it is not part of a sequence.  For curses and ANSI modes
<tr valign=top><td><b>textattr</b><td>number
<td>3.15
<td>Current text attribute
<tr valign=top><td><b>kbhit</b><td>boolean
<td>3.15
<td>True if a keystroke is pending
<tr valign=top><td><b>wherex</b><td>number
<td>3.15
<td>Current x position on the screen
<tr valign=top><td><b>wherey</b><td>number
<td>3.15
<td>Current y position on the screen
<tr valign=top><td><b>textmode</b><td>number
<td>3.15
<td>Current text mode
<tr valign=top><td><b>winleft</b><td>number
<td>3.15
<td>Left column of current window
<tr valign=top><td><b>wintop</b><td>number
<td>3.15
<td>Top row of current window
<tr valign=top><td><b>winright</b><td>number
<td>3.15
<td>Right column of current window
<tr valign=top><td><b>winbottom</b><td>number
<td>3.15
<td>Bottom row of current window
<tr valign=top><td><b>screenwidth</b><td>number
<td>3.15
<td>Width of the screen
<tr valign=top><td><b>screenheight</b><td>number
<td>3.15
<td>Height of the screen
<tr valign=top><td><b>normattr</b><td>number
<td>3.15
<td>Atrribute considered "normal"
<tr valign=top><td><b>textbackground</b><td>number
<td>3.15
<td>Background colour
<tr valign=top><td><b>textcolor</b><td>number
<td>3.15
<td>Foreground colour
<tr valign=top><td><b>clipboard</b><td>string
<td>3.15
<td>Text in the clipboard
<tr valign=top><td><b>lowvideo</b><td>boolean
<td>3.15
<td>Current attribute is low intensity
<tr valign=top><td><b>highvideo</b><td>boolean
<td>3.15
<td>Current attribute is high intensity
</table>
<h2><a name=uifc>uifc object</a>
<br><font size=-1>User InterFaCe object - used for jsexec menus</font>
<font size=-1> - introduced in v3.14</font>
</h2>
<table border=1 width=100%>
<caption align=left><b><tt>uifc</tt>
<a name=uifc_methods> methods</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Returns</font>
<th align=left width=200>
<font color="white">Usage</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>init</b><td>boolean<td><tt>uifc.init(string title [, string mode])
<td>3.14
<td>initialize.  <tt>mode</tt> is a string representing the desired conio mode... one of STDIO, AUTO, X, CURSES, ANSI, CONIO, or SDL.
<tr valign=top><td><b>bail</b><td>void<td><tt>uifc.bail()
<td>3.14
<td>uninitialize
<tr valign=top><td><b>msg</b><td>void<td><tt>uifc.msg(string text)
<td>3.14
<td>print a message
<tr valign=top><td><b>pop</b><td>void<td><tt>uifc.pop([string text])
<td>3.14
<td>popup (or down) a message
<tr valign=top><td><b>input</b><td>string<td><tt>uifc.input([number mode] [number left] [number top] [string default] [number maxlen] [number kmode])
<td>3.14
<td>prompt for a string input
<tr valign=top><td><b>list</b><td>string<td><tt>uifc.list([number mode] [string title] [string array options] [uifc.list.CTX object])
<td>3.14
<td>select from a list of options.<br>The context object can be created using new uifc.list.CTX() and if the same object is passed, allows WIN_SAV to work correctly.<br>The context object has the following properties:<br>cur, bar, top, left, width
<tr valign=top><td><b>showhelp</b><td>void<td><tt>uifc.showhelp()
<td>3.17
<td>Shows the current help text
</table>
<br>
<table border=1 width=100%>
<caption align=left><b><tt>uifc</tt>
<a name=uifc_properties> properties</a>
</b></caption>
<tr bgcolor=gray>
<th align=left width=100>
<font color="white">Name</font>
<th align=left width=100>
<font color="white">Type</font>
<th align=left width=50>
<font color="white">Ver</font>
<th align=left>
<font color="white">Description</font>
<tr valign=top><td><b>initialized</b><td>boolean
<td>3.14
<td>uifc has been initialized
<tr valign=top><td><b>mode</b><td>number
<td>3.14
<td>current mode bits (see uifcdefs.js)
<tr valign=top><td><b>changes</b><td>boolean
<td>3.14
<td>a change has occured in an input call.  You are expected to set this to false before calling the input if you care about it.
<tr valign=top><td><b>save_num</b><td>number
<td>3.14
<td>save buffer depth (advanced)
<tr valign=top><td><b>screen_length</b><td>number
<td>3.14
<td>current screen length
<tr valign=top><td><b>screen_width</b><td>number
<td>3.14
<td>current screen width
<tr valign=top><td><b>list_height</b><td>number
<td>3.14
<td>when WIN_FIXEDHEIGHT is set, specifies the hight used by a list method
<tr valign=top><td><b>esc_delay</b><td>number
<td>3.14
<td>delay before a single ESC char is parsed and assumed to not be an ANSI sequence (advanced)
<tr valign=top><td><b>help_text</b><td>string
<td>3.14
<td>text that will be displayed if F1 is pressed
<tr valign=top><td><b>background_color</b><td>number
<td>3.14
<td>background colour
<tr valign=top><td><b>frame_color</b><td>number
<td>3.14
<td>frame colour
<tr valign=top><td><b>text_color</b><td>number
<td>3.14
<td>text colour
<tr valign=top><td><b>inverse_color</b><td>number
<td>3.14
<td>inverse colour
<tr valign=top><td><b>lightbar_color</b><td>number
<td>3.14
<td>lightbar colour
</table>
<p><small>
Totals: 625 properties, 400 methods
